区块链solidity经典合约合集!技能大赛必考

Hello World合约

常用于区块链运维的console与compiler测试,最入门

pragma solidity ^0.4.25;

contract HelloWorld{
    string str;
    
    constructor() public {
        str = "Hello World";
    }
    
    function setStr(string memory _str)public {
        str = _str;
    }
    
    function getStr()public view returns(string memory){
        return str;
    }
}
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;
contract test{
    struct stu{
        uint sno;
        address sadr;
        string sname;
        uint age;
    }
    uint snum=0;
    stu[] stulist;
    mapping(address=>stu) stus;
    
    function addStu(string  _sname,uint  _age)public {
        snum++;
        stu memory s = stu(snum,msg.sender,_sname,_age);
        stus[msg.sender] = s;
        stulist.push(s);
    }
    
    function getStu(address  _saddr)public view returns(stu){
        return stus[_saddr];
    }
}

LearnSolidity合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
import "./Token.sol";

// The malicious contract that inherits from the Token contract
contract MaliciousToken is
    Token // The address of the original Token contract
{
     address public tokenAddress;
    // The constructor that sets the token address and the initial supply
    constructor(address _tokenAddress, uint256 _initialSupply)
        public
        Token(_initialSupply)
    {
        tokenAddress = _tokenAddress;
    }

    // The function that overrides the transfer function of the Token contract
    function transfer(address _to, uint256 _value)
        public
        override
        returns (bool)
    {
        // Call the transfer function of the original Token contract with self as the recipient
        (bool success, ) = tokenAddress.call(
            abi.encodeWithSignature(
                "transfer(address,uint256)",
                address(this),
                _value
            )
        );
        require(success, "Transfer failed");
        return true;
    }

    // The fallback function that calls the transfer function again
    fallback() external payable {
        // Call the transfer function of the original Token contract with self as the recipient
        (bool success, ) = tokenAddress.call(
            abi.encodeWithSignature(
                "transfer(address,uint256)",
                address(this),
                msg.value
            )
        );
        require(success, "Transfer failed");
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.10;
import "./Ownable.sol";
import "./SafeMath.sol";


contract Poll is Ownable{
    using SafeMath for uint256;
    uint public totalProposal;
    uint public totalVoter;

    struct Proposal{
        uint proposalId;//投票编号
        uint startTime;//提案时间
        address proposer;//提案用户地址
        uint endTime;//结束时间
        uint agreeNum;// 同意提案数目
        bool result;//结果
        string content;// 内容
    }

    struct Voter{
        uint timestamp;
        uint status; //0.同意;1.不同意;2.未投票
    }

    mapping (uint => Proposal) proposals;
    mapping (address => Voter) voters;

    event CreateProposal(uint createTime, uint proposalId,address proposer);
    event Vote(uint256 id, address voter, uint256 status);
    event Result(uint256 id,bool result);

    constructor(address[] memory _voters)public {
        for(uint256 i;i<_voters.length;i++){
            _setVoter(_voters[i]);
            totalVoter.add(1);
        }
    }

    modifier isVoter(){
        require(voters[msg.sender].status==2,"don't vote");
        _;
    }

    function _setVoter(address _voter) private {
        voters[_voter].status = 2;
    }

    function createProposal(uint _endTime,string memory _content)public onlyOwner{
        Proposal memory proposal = Proposal({
            proposalId:totalProposal,
            startTime:block.timestamp,
            proposer:msg.sender,
            endTime:_endTime,
            agreeNum:0,
            result:false,
            content:_content
        });
        proposals[totalProposal]=proposal;
        totalProposal.add(1);
        emit CreateProposal(proposal.startTime,proposal.proposalId,msg.sender);
    }

    function vote(uint _id,uint _status)public isVoter{
        voters[msg.sender].status=_status;
        voters[msg.sender].timestamp = block.timestamp;
        proposals[_id].agreeNum = _status==0 ? proposals[_id].agreeNum.add(1) : proposals[_id].agreeNum;
        emit Vote(_id,msg.sender,_status);
    }

    function getResult(uint _id)public view returns(bool result){
        return proposals[_id].agreeNum.mul(2)>totalVoter;
    }

    function stopVote(uint _id)public {
        require( proposals[_id].endTime < block.timestamp,"stop Voted");
        bool result = getResult(_id);
        proposals[_id].result = result;
        emit Result(_id,result);
    }


    function getProposals(uint256 _id)public view returns(uint,uint,address,uint,uint,bool,string memory){
        return (proposals[_id].proposalId,proposals[_id].startTime,proposals[_id].proposer,proposals[_id].endTime,proposals[_id].agreeNum,proposals[_id].result,proposals[_id].content);
    } 



}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

contract RecoverToken {
    mapping(address => uint256) balances;
    uint256 public totalSupply;

    // A boolean variable that indicates if the contract is locked or not
    bool private locked;

    // A modifier that checks if the contract is locked or not
    modifier noReentrancy() {
        require(!locked, "Reentrant call");
        locked = true;
        _;
        locked = false;
    }

    constructor(uint256 _initialSupply) public {
        balances[msg.sender] = totalSupply = _initialSupply;
    }

    // Add the noReentrancy modifier to the transfer function
    function transfer(address _to, uint256 _value)
        public
        noReentrancy
        returns (bool)
    {
        require(balances[msg.sender] - _value >= 0);
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        return true;
    }

    function balanceOf(address _owner) public view returns (uint256 balance) {
        return balances[_owner];
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

contract Token {
    mapping(address => uint256) balances;
    uint256 public totalSupply;

    constructor(uint256 _initialSupply) public {
        balances[msg.sender] = totalSupply = _initialSupply;
    }

    function transfer(address _to, uint256 _value) public returns (bool) {
        require(balances[msg.sender] - _value >= 0);
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        return true;
    }

    function balanceOf(address _owner) public view returns (uint256 balance) {
        return balances[_owner];
    }
}

宠物领养合约

pragma solidity ^0.4.25;
contract Adoption {
uint8 userIndex;
mapping(address => uint8) userMapping;
// 保存领养者的地址
address[8] public adopters;
constructor() public {
userIndex = 0;
}
//用户注册(返回用户注册数量)
function register(address user) public returns(uint8) {
userIndex++;
userMapping[user] = userIndex;
return userIndex;
}
//判断用户是否可以登录(>0)
function login(address user) public view returns(uint8) {
return userMapping[user];
}
// 领养宠物
function adopt(uint petId) public returns (uint) {
// 确保 id 在数组长度内
require(petId >= 0 && petId <= 7);
uint userNotExist = 404;
//用户序号为0代表未注册
if (userMapping[msg.sender] == 0) {
return userNotExist;
}
// 保存调用这地址
adopters[petId] = msg.sender;
return petId;
}
// 返回领养者
function getAdopters() public view returns (address[8] memory) {
return adopters;
}
}

单签合约

pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Seal.sol";

//主合约
contract ElectronicSeal {
    address owner; //合约拥有者
    
    //key为账户地址
    mapping(address => Seal) sealMap;

    //构造函数
    constructor() public {
        owner = msg.sender;
    }

    //判断合约调用者是否为合约拥有者
    modifier onlyOwner() {
        require(owner == msg.sender,"Only owner can call");
        _;
    }

    //添加签章账户
    function addSealAccount(address _account,string _name,string _cardId,string _datetime) public onlyOwner{
        Seal seal = new Seal(_name,_cardId,_datetime);
        sealMap[_account] = seal;
    }

    //添加账户签章信息
    function sealSignature(address _account,string _hash,string _code,string _datetime) public onlyOwner{
        Seal seal = sealMap[_account];
        seal.signature(_hash, _code,_datetime);
    }

    //查看账户信息
    function getSealAccount(address _account) view public returns(string,string,string) {
        Seal seal = sealMap[_account];
        return seal.getSealInfo();
    }

    //查看账户签章信息
    function querySignature(address _account,string _hash) view public returns(string,string) {
        Seal seal = sealMap[_account];
        return seal.getRecord(_hash);
    }

    //查看账户签章hash值
    function queryAllHash(address _account) view public returns(string[] memory) {
        Seal seal = sealMap[_account];
        return seal.getAllHash();
    }
}
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

//印章合约
contract Seal {
    //印章信息
    struct SealInfo {
        string name;  //姓名
        string cardId;//身份证
        string datatime;//创建印章时间戳
    }

    //签章记录
    struct RecordInfo {
        string code;
        string datetime;
    }

    SealInfo public sealInfo;

    //获取账户信息
    function getSealInfo() view public returns(string,string,string) {
        return (sealInfo.name,sealInfo.cardId,sealInfo.datatime);
    }

    //签章记录(key:签章文档hash值,value:签章时间戳)
    mapping(string=>RecordInfo) recordMap;
    string[] keys; 

    //构造函数
    constructor(string _name,string _cardId,string _datetime) public {
        sealInfo.name = _name;
        sealInfo.cardId = _cardId;
        sealInfo.datatime = _datetime;
    }

    function signature(string _hash,string _code,string _datetime) public {
        recordMap[_hash] = RecordInfo(_code,_datetime);
        keys.push(_hash);
    }

    function getRecord(string _hash) view public returns(string,string) {
        RecordInfo memory recordInfo = recordMap[_hash];
        return (recordInfo.code,recordInfo.datetime);
    }

    function getAllHash() view public returns(string[] memory) {
        return keys;
    }
    
}

电子签章合约

pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Seal.sol";
import "./MultiSeal.sol";

//主合约
contract ElectronicSeal {
    address owner;  //合约拥有者
    uint8 counter;  //印章账户计数器
    
    //key为签章账户地址
    mapping(address => Seal) sealMap;  //个人签章表

    //key为签章账户地址
    mapping(address => bool) signerMap; //签章账户表
    
    //key为签章发起人账户地址
    mapping(address => MultiSeal) multiSealMap; //多人签章表

    //key为签章文件编号 
    mapping(string=>MultiSeal) multiSealHistory; //多人签章历史记录表
    string[] codes;

    //key为签章发起人账户地址
    mapping(address => bool) promoterMap; //签章发起人表

    //个人签章事件
    event AddSealAccountEvent(address,string,string,string);
    event CancelSealAccountEvent(address);
    event SealSignature(address,string,string,string);

    //构造函数
    constructor() public {
        owner = msg.sender;
        counter = 0;
    }

    //判断合约调用者是否为合约拥有者
    modifier onlyOwner() {
        require(owner == msg.sender,"Only owner can call");
        _;
    }

    //判断合约调用者是否为签章发起人
    modifier onlyPromoter() {
        require(promoterMap[msg.sender] == true,"Only Promoter can call");
        _;
    }

    //判断合约调用者是否为签约账户
    modifier onlySigner() {
        require(signerMap[msg.sender] == true,"Only Signer can call");
        _;
    }

    //判断合约调用者是否签章发起人或签章账户
    modifier onlyPromoterOrSinger() {
        require(promoterMap[msg.sender] == true || signerMap[msg.sender] == true,"Only Signer or Promoter can call");
        _;
    }

    单人签名/

    //添加签章账户(_account:签章账户地址,_name:签章账户姓名,_cardID:签章账户身份证号码,_data:印章数据,_datetime:申请印章时间)
    function addSealAccount(address _account,string _name,string _cardId,string _data,string _datetime) public onlyOwner{
        Seal seal = new Seal(_name,_cardId,_data,_datetime);
        sealMap[_account] = seal;
        signerMap[_account] = true;
        counter++; //整数溢出漏洞
        emit AddSealAccountEvent(_account,_name,_cardId,_datetime);
    }
    
    //添加账户签章信息(_account:签章账户地址,_hash:签章文件摘要,_datatime:签章时间)
    function sealSignature(address _account,string _hash,string _code,string _datetime) public onlyOwner{
        require(_account != address(0));
        Seal seal = sealMap[_account];
        if (seal.getIsUsed()) {
            seal.signature(_hash, _code,_datetime);
        }
        emit SealSignature(_account,_hash,_code,_datetime); //代码逻辑漏洞
    }

    //查看账户信息(_account:签章账户地址)
    function getSealAccount(address _account) view public returns(string,string,string) {
        require(_account != address(0));
        Seal seal = sealMap[_account];
        return seal.getSealInfo();
    }

    //查看账户签章信息(_account:签章账户地址,_hash:签章文件摘要)
    function querySignature(address _account,string _hash) view public returns(string,string) {
        require(_account != address(0));
        Seal seal = sealMap[_account];
        return seal.getRecord(_hash);
    }

    //查看账户签章hash值(_account:签章账户地址)
    function queryAllHash(address _account) view public returns(string[] memory) {
        require(_account != address(0));
        Seal seal = sealMap[_account];
        return seal.getAllHash();
    }

    //注销印章账户(_account:签章账户地址)
    function cancelSealAccount(address _account) public onlyOwner{
        require(_account != address(0));
        Seal seal = sealMap[_account];
        signerMap[_account] = false;
        seal.setIsUsed(false);
        counter--; //整数溢出漏洞
        emit CancelSealAccountEvent(_account);
    }

    //查看印章数据(_account:签章账户地址)
    function getSealData(address _account) view public onlyOwner returns(string) {
        require(_account != address(0));
        Seal seal = sealMap[_account];
        return seal.getSealData();
    }

    //查看注册印章账户数量
    function getSealAccountCounter() view public onlyOwner returns(uint) {
        return counter;
    }

    /多人签名//
    
    //签章发起人注册(_address:签章发起人账户地址)
    function addPromoter(address _address) public onlyOwner {
        require(_address != address(0));
        promoterMap[_address] = true;
    }

    //是否签章发起人(_address:签章发起人账户地址)
    function isPromoter(address _address) public view onlyOwner returns(bool) {
        require(_address != address(0));
        if (promoterMap[_address]) {
            return true;
        }

        return false;
    }

    //签章发起人发起多人签章(_code:签章文件编号 _number:签章人数 _accounts:签章账户数组)
    function startMultiSign(string _code,uint _number,address[] memory _accounts) public onlyPromoter {
        require(address(multiSealMap[msg.sender]) == address(0));
        require(!isExistMultiCode(_code),"code is exist.");

        MultiSeal multiSeal = new MultiSeal(msg.sender,_code,_number,_accounts);
        multiSeal.initSigner();
        multiSealMap[msg.sender] = multiSeal;
    }

    //多人签章(_address:签章人账户地址,_hash:签章文件摘要,_datatime:签章时间戳)
    function doMultiSign(address _address,string _hash,string _datetime) public onlyPromoter {
        require(_address != address(0),"address is null");
        
        MultiSeal multiSeal = multiSealMap[msg.sender];
        address signer = multiSeal.getSigner();
        require(signer == _address,"signer is incorrect");

        multiSeal.sign(_address, _hash, _datetime);
    }

    //完成多人签章
    function finishMultiSign() public onlyPromoter {
        MultiSeal multiSeal = multiSealMap[msg.sender];
        require(multiSeal.signStatus() == MultiSeal.SignStatus.FINISH,"status is signing.");

        //存储多人签章记录
        string memory code = multiSeal.getCode();
        multiSealHistory[code] = multiSeal; 
        codes.push(code);

        //清除表数据
        multiSealMap[msg.sender] = MultiSeal(address(0));
    }

    //获取多人签约信息(_code:签章文件编号)
    function getMultiSingInfo(string _code) public view onlyPromoterOrSinger returns(string,address,string,uint,address[] memory) {
        //①获取多人签章合约对象实例
        require(isExistMultiCode(_code),"code is not exist");
        MultiSeal  multiSeal = multiSealHistory[_code];
        return multiSeal.multiSingInfo();
    } 
    
    //获取所有多人签名文件编号
    function getCodes() view public onlyOwner() returns(string[] memory){
        return codes;
    }

    //签章账户查看签章记录(多人)
    //返回值:签章账户所参与多人签章的所有文件编号
    function getSingInfoFromSigner() view public onlySigner returns(string[] memory) {
        string[] memory _codes = new string[](codes.length);
        uint num = 0;

        //获取签约文件编号
        for (uint index = 0; index < codes.length; index++) {
            string memory code = codes[index];
            MultiSeal multiSeal = multiSealHistory[code];
            if (keccak256(bytes(code)) == keccak256(bytes(multiSeal.multiSingInfoFromSigner(msg.sender)))) {
                _codes[index] = multiSeal.getCode();
                num++;
            }
        }

        //整理签约文件编号数组(去空值)
        string[] memory codeArr = new string[](num);
        uint sn = 0;
        for (uint ind = 0; ind < _codes.length; ++ind) {
            if (bytes(_codes[ind]).length != 0) {
                codeArr[sn] = _codes[ind];
                sn++;
            }
        }

        return codeArr;
    }

    //判断多人签名文件编号是否存在 (_code:签章文件编号)
    function isExistMultiCode(string _code) view internal returns(bool) {
        for (uint index = 0; index < codes.length; ++index) {
            if (keccak256(bytes(_code)) == keccak256(bytes(codes[index]))) {
                return true;
            }
        }
        return false;
    }
}
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

//多人印章合约
contract MultiSeal {
    string hash;        //签约文件摘要(hash) 
    address promoter;   //签章发起人账户地址   
    string code;        //签章文件编号
    uint number;        //签约账户个数
    address[] accounts; //签章账户列表 
    mapping(address=>RecordInfo) recordMap;  //签章记录
    SignStatus status;

    //签章状态枚举    
    enum SignStatus {
        START,    //发起签章
        SIGNING,  //签章中
        FINISH    //完成签章
    }

    //签章记录结构体
    struct RecordInfo {
        bool isSigned;   //是否签章
        string hash;     //签章文件摘要(hash)
        string datetime; //签章时间戳
    }

    //构造函数(_address:签章发起人账户地址,_code:签章文件编号 _number:签章人数 _accounts:签章账户数组)
    constructor(address _address,string _code,uint _number,address[] memory _accounts) public {
        code = _code;
        number = _number;
        accounts = _accounts;
        promoter = _address;
        status = SignStatus.START;
    }

    //初始化签章账户状态
    function initSigner() public {
        for (uint index = 0; index < accounts.length; ++index) {
            address _address = accounts[index];
            recordMap[_address] = RecordInfo(false,"0","0");
        }
    }

    //获取准备签章账户地址
    function getSigner() view public returns(address){
        for (uint index = 0; index < accounts.length; ++index) {
            address _address = accounts[index];
            RecordInfo storage recordInfo = recordMap[_address];
            if (!recordInfo.isSigned) {
                return _address;
            }
        }
        return address(0);
    }

    //获取签章文件编号
    function getCode() view public returns(string) {
        return code;
    }

    //签章(_address:签章账户地址 _hash:签章文件摘要 _datetime:签章时间)
    function sign(address _address,string _hash,string _datetime) public {
        require(status == SignStatus.START || status == SignStatus.SIGNING,"status is error");

        RecordInfo storage recordInfo = recordMap[_address];
        recordInfo.isSigned = true;
        recordInfo.hash = _hash;
        recordInfo.datetime = _datetime;
        status = SignStatus.SIGNING;

        //设置签章状态
        if(isFinish()) {
            hash = _hash;
            status = SignStatus.FINISH;
        }
    }

    //获取当前签章状态
    function signStatus() view public returns(SignStatus){
        return status;
    }

    //是否完成签章
    //返回值 true:完成签章 false:未完成签章
    function isFinish() view internal returns(bool) {
        for (uint index = 0; index < accounts.length; ++index) {
            address _address = accounts[index];
            RecordInfo storage recordInfo = recordMap[_address];
            if (!recordInfo.isSigned) {
                return false;
            }
        }
        return true;
    }

    //获取多人签约信息
    //返回值:(签章文件摘要,签章发起人,签章文件编号,签章人数,签章账户数组)
    function multiSingInfo() view public returns(string,address,string,uint,address[] memory) {
        return (hash,promoter,code,number,accounts);
    }

    //根据签章人获取多人签章信息(签章人账户地址)
    //返回值:签章文件编号
    function multiSingInfoFromSigner(address _address) view public returns(string memory) {
        require(_address != address(0));
        for (uint index = 0; index < accounts.length; ++index) {
            if (_address == accounts[index]) {
                return code;
            }
        }
    }
}    

pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

//印章合约
contract Seal {    
    bool isUsed; //印章状态

    //印章信息
    struct SealInfo {
        string name;  //姓名
        string cardId;//身份证
        string data;  //印章数据
        string datetime;//创建印章时间戳
    }

    //签章记录
    struct RecordInfo {
        string code;
        string datetime;
    }

    SealInfo public sealInfo;

    //签章记录(key:签章文档hash值,value:签章记录)
    mapping(string=>RecordInfo) recordMap;
    string[] keys; 

    //构造函数
    constructor(string _name,string _cardId,string _data,string _datetime) public {
        sealInfo.name = _name;
        sealInfo.cardId = _cardId;
        sealInfo.data = _data;
        sealInfo.datetime = _datetime;
        isUsed = true;
    }

     //设置印章状态
    function setIsUsed(bool _status) public {
        isUsed = _status;
    }

    //获取印章状态
    function getIsUsed() view public returns(bool) {
        return isUsed;
    }

    //获取印章数据
    function getSealData() view public returns(string) {
        return sealInfo.data;
    }

    //获取账户信息
    function getSealInfo() view public returns(string,string,string) {
        return (sealInfo.name,sealInfo.cardId,sealInfo.datetime);
    }

    //签章
    function signature(string _hash,string _code,string _datetime) public {
        recordMap[_hash] = RecordInfo(_code,_datetime);
        keys.push(_hash);
    }

    //获取签章记录
    function getRecord(string _hash) view public returns(string,string) {
        RecordInfo memory recordInfo = recordMap[_hash];
        return (recordInfo.code,recordInfo.datetime);
    }

    //获取所有签章摘要(hash)
    function getAllHash() view public returns(string[] memory) {
        return keys;
    }
    
}

 

房屋租聘合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.4.25;

contract HouseInformation {
    // 房产所有者映射
    mapping(uint256 => address) public ownerOf;
    // 地址对应的房产ID数组映射
    mapping(address => uint256[]) public ownedHouses;
    //选手填写部分
	//①房产ID对应的被授权地址映射
	mapping(uint256=> address) public approved;
	
	//②房产ID对应的房产数据映射
	mapping (uint256=>HouseData)public houseData;
	//③转移房产事件,参数为indexed  from,indexed  to,houseId
    event Transfer(address indexed from, address indexed to, uint256 houseId);
    
    uint256  houseNumber;
    // 转移房产事件
    //event Transfer(address indexed from, address indexed to, uint256 houseId);

    // 授权事件
    event Approval(address indexed owner, address indexed spender, uint256 houseId);

    // 房产数据结构体
    struct HouseData {
        //选手填写部分
        //④房产描述
        string description;
        //⑤房产价格
        uint256 price;
    }
    
    //创建新的房产信息
    function createHouse(address to, string memory description, uint256 price) public  returns (uint256) {
        //选手填写部分
        //①房产数量累加1
        houseNumber++;
        //②判断房产是否被创建过
        require(ownerOf[houseNumber]==address(0),"aaaa");
        //③设置房产的拥有者
        ownerOf[houseNumber]=to;
        //④将房产编号添加到房产用户的房产编号列表中
        ownedHouses[to].push(houseNumber);
        //⑤设置房产编号对应的房产信息
        HouseData memory data=HouseData(description,price);
        houseData[houseNumber]=data;
        //⑥触发转移房产事件
         emit Transfer(to,to,houseNumber);
        return houseNumber;
    }

    // 转移房产
    function transfer(address from, address to, uint256 houseId) public returns (bool) {
        //选手填写部分
        //①验证from是否为房产所有者
        require(from==ownerOf[houseId],"you are not owner");
        //②验证当前交易的发起者是否为房产所有者 或者  已授权的房产是否为当前交易发起者
        require((msg.sender==from)||(msg.sender==approved[houseId]),"no");
        //③从发送者的房产拥有列表中删除房产
        for(uint i=0;i<ownedHouses[ownerOf[houseId]].length;i++){
            if(ownedHouses[ownerOf[houseId]][i]==houseId){
                ownedHouses[ownerOf[houseId]][i]==ownedHouses[ownerOf[houseId]][ownedHouses[ownerOf[houseId]].length-1];
                ownedHouses[ownerOf[houseId]][ownedHouses[ownerOf[houseId]].length-1]=0;
            }
        }
        //④将房产添加到接收者的房产拥有列表中
        ownerOf[houseId]=to;
        ownedHouses[to].push(houseId);
        //⑤重置授权
        approved[houseId]=to;
        emit Transfer(from, to, houseId);
        return true;
    }

    // 授权转移房产
    function approve(address spender, uint256 houseId) public returns (bool) {
        require(ownerOf[houseId] == msg.sender, "非房产所有者");
        approved[houseId] = spender;
        emit Approval(msg.sender, spender, houseId);
        return true;
    }

    // 获取房产被授权的地址
    function getApproved(uint256 houseId) public view returns (address) {
        return approved[houseId];
    }

    // 获取房产数据
    function getHouseData(uint256 houseId) public view returns (string memory description, uint256 price) {
        HouseData memory data = houseData[houseId];
        return (data.description, data.price);
    }

    // 根据地址获取拥有的房产列表
    function getOwnedHouses(address houseOwner) public view returns (uint256[] memory) {
        return ownedHouses[houseOwner];
    }

    // 根据地址获取被授权的房产列表
    // function getApprovedHouses(address spender) public view returns (uint256[] memory) {
    //     return approvedHouses[spender];
    // }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.25;

import "./HouseInformation.sol";
import "./Ownable.sol";

contract HouseLease is Ownable {
    HouseInformation public houseContract; // HouseInformation合约的实例

    uint256 public agreementNumber; //合同的数量
    //合同列表
    mapping(uint256 => Agreement) public agreements;
    //合同账户信息
    mapping(uint256 => AgreementAccount) public agreementAccounts;
    //房东签约的合同列表
    mapping(address => uint[]) public landlordToAgreementIds;
    //租客签约的合同列表
    mapping(address => uint[]) public tenantToAgreementIds;

    struct Agreement {
        //选手填写部分
        //①房屋ID
        uint256 houseID;
        //②房东地址
        address landlord;
        //③租客地址
        address tenant;
        //④每月租金金额
        uint256 rentAmount;
        //⑤租赁开始日期
        uint256 leaseStartDate;
        //⑥租赁结束日期
         uint256 leaseEndDate;
        //⑦是否已签署 0 都未签署、1 已签署、2 房东签署,租客未签署、3 租客签署,房东未签署、4 房东终止合约、5 租客终止合同、6 取消、 7 租金不足
        uint8 sign;
    }
   


    struct AgreementAccount {
        //选手填写部分
      //⑧已付租金
      uint256 paidAmount; 
      //⑨押金 押金为租金的三倍
      uint256 cashPledge;
      //⑩已经花费租金
      uint256 spendedToken;
      uint256 alreadyAmount; // 已提取的租金额度
    }

    //租客列表
    mapping(address => uint256) public accounts;

    

    //创建合约对象
    constructor(address _houseInformation) public {
        houseContract = HouseInformation(_houseInformation);
    }

    modifier isLandlord(address _landlord, uint256 _houseID) {
        require(
            houseContract.ownerOf(_houseID) == _landlord,
            "此房屋不属于此用户"
        );
        _;
    }

    modifier isHouseApproved(uint _houseID) {
        require(
            houseContract.getApproved(_houseID) == address(this),
            "没有授权无法操作"
        );
        _;
    }
    //是否签署
    modifier isSigned(uint _agreementId) {
        require(agreements[_agreementId].sign == 1);
        _;
    }

    //创建租客,存储初始账户金额
    function createAccounts(address _tenant,uint amount) public onlyOwner{
        accounts[_tenant]=amount;
    }
    //租客账户充值
    function transferAccounts(uint amount) public{
        accounts[msg.sender]+=amount;
    }

    // 创建租赁合同
    function createAgreement(uint256 _houseID,address _tenant,uint256 _rentAmount,uint256 _leaseStartDate,
        uint256 _leaseEndDate
    )
        public
        isLandlord(msg.sender, _houseID)
        isHouseApproved(_houseID)
        returns (uint256)
    {
        //选手填写部分
        //①合同数量+1
        agreementNumber++;
        //②将合同编号添加到房东拥有合同编号列表中
        landlordToAgreementIds[msg.sender].push(agreementNumber);
        //③将合同编号添加到租客拥有合同编号列表中
        tenantToAgreementIds[_tenant].push(agreementNumber);
        //④创建合同信息
        agreements[agreementNumber]=Agreement(_houseID,msg.sender,_tenant,_rentAmount,_leaseStartDate,_leaseEndDate,0);
        //⑤初始化合同账户信息
        agreementAccounts[agreementNumber]=AgreementAccount(0,0,0,0);
        return agreementNumber;
    }

    // 房东签署合同
    function landlordSigning(
        uint256 _agreementId
    )
        public
        isLandlord(msg.sender, agreements[_agreementId].houseID)
        isHouseApproved(agreements[_agreementId].houseID)
        returns (bool)
    {
        //选手填写部分
        //①获取合同对象
        Agreement storage agreement= agreements[_agreementId];
        //②验证房东是否能够进行签名
        require(agreement.sign==0,"no sign");
        //③将该房产转移给到合约
        houseContract.transfer(
            address(this),
            agreements[_agreementId].tenant,
            agreements[_agreementId].houseID
        );
        //④修改合同签约状态
        agreement.sign=2;
        return true;
    }

    // 租客签署合同
    function tenantSigning(uint256 _agreementId) public returns (bool) {
        //选手填写部分
        //①根据签名状态判断租客是否可以进行签名
        require(agreements[_agreementId].sign==2,"aaa");
        //②判断租户的账户金额是否足够支付4倍房租
        require(accounts[msg.sender]>=(4*agreements[_agreementId].rentAmount),"bugou");
        //③获取合同对象
        Agreement storage agreement=agreements[_agreementId];
        //④获取合同账户对象
        AgreementAccount storage agreementAccount=agreementAccounts[_agreementId];
        //⑤设置押金
        agreementAccount.cashPledge=3*agreement.rentAmount;
        //⑥设置支付的房租
        agreementAccount.paidAmount=agreement.rentAmount;
        //⑦租户账户金额减少4倍租金
        accounts[msg.sender]-=4*agreementAccount.cashPledge;
        //⑧房东账户增加4倍
        accounts[agreement.landlord]+=4*agreementAccount.cashPledge;
        //⑨合同状态变成已签署
        agreement.sign=1;
        return true;
    }

    // 租客支付租金
    function payment(uint256 _agreementId,uint256 amount) public isSigned(_agreementId) returns (uint256) {
        accounts[msg.sender] -= amount;
        agreementAccounts[_agreementId].paidAmount += amount;
        //房东账户增加
        accounts[agreements[_agreementId].landlord]+= amount;
        return amount;
    }

    // 房东解除合同
    function landlordTerminates(uint256 _agreementId) public isSigned(_agreementId) returns (bool) {
        //选手填写部分
        //①判断当前用户是否为房东
        require(msg.sender==agreements[_agreementId].landlord,"bushi");
        //②获取需要退还的金额
        uint256 refund = calculateRefund(_agreementId);
        //③设置合同签约状态为房东解除合同
        agreements[_agreementId].sign = 4;
        //④退还押金,租户账户增加押金,房东账户减少
        accounts[agreements[_agreementId].tenant] += agreementAccounts[_agreementId].cashPledge;
        accounts[agreements[_agreementId].landlord] -=agreementAccounts[_agreementId].cashPledge;
        //⑤调用退还函数:
         abolishContract(_agreementId, refund);
        return true;
    }

    // 租户解除合同
    function tenantTerminates(uint256 _agreementId) public isSigned(_agreementId) returns (bool) {
        require(msg.sender == agreements[_agreementId].tenant);
        agreements[_agreementId].sign = 5;
        //直接计算需要返的金额
        uint256 refund = calculateRefund(_agreementId);
        //调用退还函数
        abolishContract(_agreementId, refund);

        return true;
    }
    
    function getTime() public returns(uint256){
        return block.timestamp;
    }

    // 获取已经花费的租金
    function getSpendedToken(uint256 _agreementId) public returns (uint256) {
        AgreementAccount storage agreementAccount = agreementAccounts[
            _agreementId
        ];
        Agreement storage agreement = agreements[_agreementId];
        uint256 spendedTime;
        uint256 spendedToken;
        spendedTime = ((block.timestamp - agreement.leaseStartDate) / 1 days) / 1000;
        spendedToken = (spendedTime * agreement.rentAmount) / 30;
        agreementAccount.spendedToken = spendedToken;
        return spendedToken;
    }


    //计算需要退还的金额
    function calculateRefund(uint256 _agreementId) public returns (uint256) {
        //获取合同账户
        AgreementAccount storage agreementAccount = agreementAccounts[
            _agreementId
        ];
        //获取实际需要花费的租金
        uint256 spendedToken = getSpendedToken(_agreementId);
       
        //如果实际需要花费的租金>agreementAccount.paidAmount已付租金,则返回0
        //否则退回支付的租金 - 实际花费的租金
        return
            spendedToken > agreementAccount.paidAmount
                ? 0
                : agreementAccount.paidAmount - spendedToken;
    }
    
    //退还
    function abolishContract(uint256 _agreementId, uint256 _refund) private {
        require(
            msg.sender == agreements[_agreementId].landlord ||
                msg.sender == agreements[_agreementId].tenant
        );
       
        //账户金额>需要退还的金额
        require(accounts[agreements[_agreementId].landlord] > _refund, "余额不足");
        
        //退还房屋的所有者
        houseContract.transfer(
            address(this),
            agreements[_agreementId].landlord,
            agreements[_agreementId].houseID
        );
        //退还多支付的金额
        accounts[agreements[_agreementId].tenant] += _refund;
        accounts[agreements[_agreementId].landlord] -= _refund;
        
        uint256 spendedToken = getSpendedToken(_agreementId);
        agreementAccounts[_agreementId] = AgreementAccount({
            paidAmount: spendedToken,
            cashPledge: 0,
            spendedToken: spendedToken,
            alreadyAmount: spendedToken
        });
    }

    function getLandlordAgreementIds(address _landlord) public view returns (uint[]) {
        return landlordToAgreementIds[_landlord];
    }
    
   function getAgreement(uint256 agreementId) public view returns (uint256,address,address,uint256) {
        Agreement memory agreement=agreements[agreementId];
        return (agreement.houseID,agreement.landlord,agreement.tenant,agreement.sign);
   }
   function getAgreementNumber() public view returns (uint256) {
        return agreementNumber;
   }

    function getTenantAgreementIds(
        address _tenant
    ) public view returns (uint[]) {
        return tenantToAgreementIds[_tenant];
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.25;

contract Ownable {
    address public owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() public {
        owner = msg.sender;
        emit OwnershipTransferred(address(0), owner);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not the owner");
        _;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid new owner");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }
    
    function getOwner() public view returns (address) {
        return owner;
    }
}

供应链金融合约

金融一

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;

  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }


  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }


  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}
pragma solidity ^0.4.22;
import './Ownable.sol';

//供应链金融智能合约
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 superviosrIns;

    //公司地址的数组
    address[] public companies;

    //银行地址的数组
    address[] public banks;

    //数字发票的索引
    uint public receiptIndex;
    
    //构造函数
    constructor(string name) {
        receiptIndex = 0;
        superviosrIns = Supervisor(name, msg.sender);
    }
    
    
    function addCompany(string name, address companyAddress) returns(bool) {
	//开辟两个动态数组并初始化长度为0
        Company memory newCompany = Company(name, companyAddress, 0, new uint[](0), new uint[](0));
        companies.push(companyAddress);
        companyMap[companyAddress] = newCompany;
        return true;
    }
    
    function getCompany(address companyAddress) public view returns(string, address, uint, uint[], uint[]) {
        Company company = companyMap[companyAddress];
        return (company.companyName, company.companyAddress, company.creditAsset, company.acceptReceiptIndex, company.sendReceiptIndex);
    }
    
    function addBank(string name, address bankAddress, uint credit) public onlyOwner {
        Bank memory newBank = Bank(name, bankAddress, credit, new uint[](0), new uint[](0));
        banks.push(bankAddress);
        bankMap[bankAddress] = newBank;
    }
    
    function getBank(address bankAddress) public view returns(string, address, uint, uint[], uint[]){
        Bank bank = bankMap[bankAddress];
        return (bank.bankName, bank.bankAddress, bank.creditAsset, bank.acceptReceiptIndex, bank.sendReceiptIndex);
    }
    
    function getAllCompanyAddress() public view returns(address[]) {
        return companies;
    }
    
    function getAllBankAddress() public view returns(address[]) {
        return banks;
    }
    
    function getReceipt(uint index) public view returns(address, address, uint8, uint8, uint) {
        Receipt 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) returns(uint) {
       
       //transferType :1 银行转账给公司
       //必须只能接受人创建此交易,也就是接受人承认这笔交易存在
        require(msg.sender == accepterAddress);
        Bank memory bank = bankMap[accepterAddress];
        Company memory company = companyMap[senderAddress];
        
        //确认银行存在
        if (keccak256(bank.bankName) == keccak256("")) {
            return 404001;
        }
        
        //确认公司存在
        if (keccak256(company.companyName) == keccak256("")) {
            return 404002;
        }
        
        if (bank.creditAsset < amount) {
            return 500001;
        }
        
        Receipt memory newReceipt = Receipt(senderAddress, accepterAddress, receiptType, 1, amount);
        receiptIndex += 1;
        receiptMap[receiptIndex] = newReceipt;
        companyMap[senderAddress].sendReceiptIndex.push(receiptIndex);
        bankMap[accepterAddress].acceptReceiptIndex.push(receiptIndex);
        bankMap[accepterAddress].creditAsset -= amount;
        companyMap[senderAddress].creditAsset += amount;
        return 200;
    
    }
    
    
    //公司与公司交易
    //接收存证的公司需要给发送存证的公司转账存证对应的数额
    function companyToCompanyReceipt(address senderAddress, address accepterAddress, uint amount, uint8 receiptType) returns(uint) {
        
        //transferType :2 公司与公司间转账
        //存证接收的公司可以产生这一笔交易
        require(msg.sender == accepterAddress);
        
        Company memory senderCompany = companyMap[senderAddress];
        Company memory accepterCompany = companyMap[accepterAddress];
        //确认发送公司存在
        if (keccak256(senderCompany.companyName) == keccak256("")) {
            return 404001;
        }
        
        //确认接收公司存在
        if (keccak256(accepterCompany.companyName) == keccak256("")) {
            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) returns(uint) {

        //transferType :3 公司向银行转账
        //存证接收的公司可以产生这一笔交易
        require(msg.sender == accepterAddress);
        
        Bank memory bank = bankMap[senderAddress];
        Company memory accepterCompany = companyMap[accepterAddress];
        
        //确认发送公司存在
        if (keccak256(bank.bankName) == keccak256("")) {
            return 404001;
        }
        
        //确认接收公司存在
        if (keccak256(accepterCompany.companyName) == keccak256("")) {
            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;
        
    }

}

金融二

//SPDX-License-Identifier: GPL-3.0 

pragma solidity ^0.6.9;

contract Role {
    //成员类型(1:生产商 2:收购商 3:运输商 4:销售商)
    mapping(address=>uint) userRoleMap;
    
    function addRole(address userAddress,uint role)public {
        userRoleMap[userAddress] = role;
    }
    
    function getUserRole(address userAddress)public view returns(uint) {
        uint role = userRoleMap[userAddress];
        return role;
    }
}

//SPDX-License-Identifier: GPL-3.0 

pragma solidity ^0.6.9;

contract Support{
    //食物结构体
    struct Food {
        //食品编号id
        uint id;
        //食品名称name
        string name;
        //食品类型foodType
        string foodType;
        //食品质量、
        string quality;
        //规格spec
        string spece;
        //其他信息other
        string other;
        //更新时间updateTime
        uint updateTime;
    }
    
    //生产订单结构体
    struct Productions {
        //总订单号
        uint orderNor;
        //食品订单号
        uint produceNo;
        //订单类型(1:直接付款  2:凭证)
        uint orderType;
        //产品编号
        uint foodId;
        //单价
        uint price;
        //生产数量
        uint num;
        //更新时间
        uint updateTime;
        //订单创建人
        address createUser;
    }
    
    //用户结构体
    struct Member {
        string company;
        string location;
        string tel;
        string incharge;//负责人
        string mianBusiness;
        uint creadit; //信誉分
        uint businessType;//成员类型(1:生产商 2:收购商 3:运输商 4:销售商)
        address userAddress;
        uint updateTime;
    }
    
    //购买结构体
    struct Buys {
        uint orderNo;
        uint buyNo;
        uint orderType;
        uint foodId;
        uint price;
        uint num;
        uint updateTime;
        address createUser; //订单创建人
    }
    
    
    //运输结构体
    struct Transports {
        uint orderNo;
        uint transportNo;
        uint orderType;
        uint num;
        string from_place;
        string to_place;
        uint updateTime;
        address createUser; //创建人
    }
}
//SPDX-License-Identifier: GPL-3.0 

pragma solidity ^0.6.9;
pragma experimental ABIEncoderV2;

import "./Role.sol";
import "./Support.sol";

contract Trace is Role,Support {
    address public owner;
    
    constructor()public {
        owner = msg.sender;
    }
    
    event CreateFood(uint,string);
    
    mapping(uint256 => Food) foodMap;
    mapping(uint256 => Buys) buyMap;
    mapping(uint256 => Transports) transportMap;
    mapping(address => Member) memberMap;
    mapping(uint256 => address) foods;
    
    /**根据食品信息结构体,完成食品信息添加相应功能*/
    function createfood(uint foodId,string memory name,string memory foodType,string memory quality,string memory spec,string memory other)public returns(uint) {
        foodMap[foodId] = Food(foodId,name,foodType,quality,spec,other,now);
        emit CreateFood(foodId,name);
        return foodId;
    }
    
    /** 编写食品溯源收购商创建收购订单功能*/
    function Buy(uint orderNo, uint buyNo, uint ordertype,uint foodId, uint price, uint num) public returns(uint) {
        require(userRoleMap[msg.sender] ==2 || msg.sender == owner);
        buyMap[buyNo] = Buys(orderNo,buyNo, ordertype, foodId,price,num,now,msg.sender);
        return buyNo;
    }
    
    // (3) 编写食品溯源创建运输订单功能。
    function Transport(uint orderNo,uint transportNo, uint orderType, uint num,string memory from_place,string memory to_place)public returns(uint) {
        require(userRoleMap[msg.sender] == 3 || msg.sender == owner);
        transportMap[transportNo] = Transports(orderNo,transportNo, orderType, num, from_place, to_place,now,msg.sender);
        return transportNo;
    }
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
    
    // (3) 编写食品溯源修改角色功能。 (2分)
    function changeRole(address userAddress,uint newrole) public onlyOwner{
        userRoleMap[userAddress] = newrole;
        Member storage member= memberMap[userAddress];
        member.businessType = newrole;
        memberMap[userAddress] = member;
    }
    
    // 3.补全createMember和getMember方法 (1分)
    // 基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createMember和getMember方法.
    function createMember(
        string calldata _company,
        string calldata _location,
        string calldata _tel,
        string calldata _incharge,
        uint _businessType,
        address _userAddress)
        external returns (bool) {
        memberMap[_userAddress] = Member(_company,_location,_tel,_incharge,"",10,_businessType,_userAddress,now);
        return true;
    }
    
    //获取会员信息
    function getMember(address _userAddress) public view returns (Member memory _memory) {
        Member memory _member = memberMap[_userAddress];
        return _member;
    }
    
    // 4.测试createOrder和getOrder方法 (1分)
    // 基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的create0rder和get0rder方法。
    function createOrder(uint _orderNo,uint _buyNo,uint _orderType,uint _foodId,uint _price,uint _num) external returns (bool) {
        buyMap[_orderNo] = Buys(_orderNo,_buyNo,_orderType,_foodId,_price,_num,now,msg.sender);
        return true;
    }
    
    //获取订单信息
    function getOrder(uint _orderNo) external view returns (Buys memory buys) {
        return buyMap[_orderNo];
    }
    
    //5.测试createFood和getFood方法(1分)
    // 基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createFood和getFood方法。
    function getFood(uint _id) external view returns (Food memory food) {
        return foodMap[_id];
    }
}

航班延误险合约(未完善版)

// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.7.0;
import "./FlightDelayInsurance .sol";
contract Claims is  FlightDelayInsurance{
  
    // 定义航班信息结构体
    struct Flight {
        uint256 departureTime; // 航班出发时间
        uint256 delayTime; // 航班延误时间
        bool isDelayed; // 航班是否延误
        bool isInsured; // 航班是否购买保险
    }
    
    // 定义保险公司地址
    address public insuranceCompany;
    
    // 定义航班信息映射
    mapping(bytes32 => Flight) public flights;
    
    // 定义购买保险事件
    event BuyInsurance(bytes32 flightKey, address passenger, uint256 premium);

    // 定义航班延误事件
    event FlightDelay(bytes32 flightKey, uint256 delayTime);
    
    // 定义理赔事件
    event Claim(bytes32 flightKey, address passenger, uint256 amount);

    // 定义保险公司预存的赔偿金
    uint256 public compensationNew;
    
    // 构造函数,初始化保险公司地址和赔偿金
    constructor() FlightDelayInsurance(platformS,airlineV,insuranceCompanyC,premium,compensation){
        insuranceCompany = msg.sender;
        compensationNew = compensation;
    }
    
    // 更新航班信息函数
    function updateFlight(bytes32 flightKey, uint256 departureTime, uint256 delayTime, bool isDelayed) payable public {
        // 判断调用者是否为保险公司
        require(msg.sender == insuranceCompany, "Only insurance company can update flight information");
        // 更新航班信息
        flights[flightKey].departureTime = departureTime;
        flights[flightKey].isDelayed = isDelayed;
/*********** 客户理赔接口 **********/


/********** 客户理赔接口 ***********/   

/*********** 保险公司收取保费接口开发 **********/


/********** 保险公司收取保费接口开发 ***********/  
  // 触发航班延误事件
        emit FlightDelay(flightKey, delayTime); 
    }
}
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.7.0;
contract FlightDelayInsurance {
    address public platformS; // 平台S的地址
    address public airlineV; // 航空公司V的地址
    address public insuranceCompanyC; // 保险公司C的地址
    uint public premium; // 保险费
    uint public compensation; // 赔偿金额
    uint public purchaseTime; // 购买保险的时间
    uint public depositTime; // 存入赔偿金额的时间
    bool public purchased; // 是否购买了保险
    bool public deposited; // 是否存入了赔偿金额
    mapping(address => bool) public insured; // 已退保的用户
    mapping(address => bool) public policy; // 已生成保单的用户
    mapping(address => bool) public purchasedTicket; // 已购买机票的用户

    constructor(address _platformS, address _airlineV, address _insuranceCompanyC, uint _premium, uint _compensation) {
        platformS = _platformS; // 初始化平台S的地址
        airlineV = _airlineV; // 初始化航空公司V的地址
        insuranceCompanyC = _insuranceCompanyC; // 初始化保险公司C的地址
        premium = _premium; // 初始化保险费
        compensation = _compensation; // 初始化赔偿金额
    }
    function purchaseTicket() public {
        require(!purchasedTicket[msg.sender], "Ticket has already been purchased"); // 该用户已购买机票
        purchasedTicket[msg.sender] = true; // 标记该用户已购买机票
        purchaseTime = block.timestamp;
    }
    /*********** 航班保险购买上链接口开发 **********/


    /********** 航班保险购买上链接口开发 ***********/    
    function depositCompensation() public payable {
        require(msg.sender == insuranceCompanyC, "Only insurance company C can deposit compensation"); // 只有保险公司C可以存入赔偿金额
        require(msg.value == compensation, "Compensation amount is incorrect"); // 赔偿金额不正确
        require(block.timestamp < depositTime + 2 hours, "Deposit time has expired"); // 存入赔偿金额的时间已过期
        deposited = true; // 标记已存入赔偿金额
    }

    /*********** 退保接口开发 **********/
    

    /********** 退保接口开发 ***********/   

    function generatePolicy() public {
        require(deposited, "Compensation has not been deposited"); // 赔偿金额未存入,无法生成保单
        require(msg.sender == platformS, "Only platform S can generate policy"); // 只有平台S可以生成保单
        require(!policy[msg.sender], "Policy has already been generated"); // 该用户已生成保单
        policy[msg.sender] = true; // 标记该用户已生成保单
    }
}
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.7.0;

contract FlightManagement {
    
    // 航班结构体
    struct Flight {
        string flightNumber; // 航班号
        uint256 scheduledDepartureTime; // 计划起飞时间
        uint256 actualDepartureTime; // 实际起飞时间
        uint256 arrivalTime; // 到达时间
        bool delayed; // 是否延误
    }
    
    // 航班号到航班信息的映射
    mapping(string => Flight) flights;
    
    // 添加航班
    function addFlight(string memory _flightNumber, uint256 _scheduledDepartureTime, uint256 _arrivalTime) public {
        flights[_flightNumber] = Flight(_flightNumber, _scheduledDepartureTime, 0, _arrivalTime, false);
    }
    
    // 更新实际起飞时间
    function updateActualDepartureTime(string memory _flightNumber, uint256 _actualDepartureTime) public {
        flights[_flightNumber].actualDepartureTime = _actualDepartureTime;
    }
        
/*********** 获取航班信息接口开发 **********/


/********** 获取航班信息接口开发 ***********/   

/*********** 编写判断航班是否延误接口开发 **********/


/********** 编写判断航班是否延误接口开发 ***********/   
}

食品溯源合约

23年广东省技能大赛题

pragma solidity ^0.4.25;
/**支持struct结构体的数据返回*/
pragma experimental ABIEncoderV2;
contract TraceFruit{
   /**定义产品的结构体*/
    struct Product {
        string name;//产品名称
        uint256 productType;//产品种类,0,1,2,3,4
        string operatorName;//操作员
        uint256 timestamp;//时间
            
    }
    /**定义溯源数据的结构体*/
    struct ProductData {
        uint256 traceNumber;
        Product product;
        MiddlemanData middleman;
        SuperMarketData superMarket;
        bool valid;
    }
    /**定义中间商数据结构体*/
    struct MiddlemanData {
        string operatorName;//操作员
        uint256 quality;//质量
        uint256 timestamp;//时间
    }
    /**定义超市数据结构体*/
        struct SuperMarketData {
            string operatorName;//操作员
            uint256 quality;//质量
            uint256 timestamp;//时间
    }
    /**定义一个map,key为溯源码,value为溯源数据*/
    mapping(uint256 => ProductData) private _product;
    
    /**定义三个溯源信息添加事件**/
    event newProduct(uint256 traceNumber,string productName,uint256 productType,address productor);
    event addTraceInfoByMiddleman_event(uint256 traceNumber,uint256 quality,string operatorName);
    event addTraceInfoBySuperMarket_event(uint256 traceNumber,uint256 quality,string operatorName);
    
    /**************************************************************/
    //定义几个adress
    address owner;
    address farmer;
    address middleMan;
    address superMarket;
    
    constructor(address _farmer,address _middleMan,address _superMarket)public{
        owner=msg.sender;
        farmer=_farmer;
        middleMan=_middleMan;
        superMarket=_superMarket;
    }
    
    modifier onlyFarmer(){
        require(msg.sender==farmer,"你不是农场者");
        _;
    }
    
    
    modifier onlyMiddleMan(){
        require(msg.sender==middleMan,"你不是中间商");
        _;
    }
    
    modifier onlySuperMarket(){
        require(msg.sender==superMarket,"你不是超市");
        _;
    }
    
    /**************************************************************/
    
    /**新增产品函数,传入溯源码,操作者,产品名和产品种类*/
    function addProduct(uint256 traceNumber,string operatorName,string productName,uint256 productType) onlyFarmer public {
     require(!_product[traceNumber].valid,"This product is exist");
     Product memory product =Product(productName,productType,operatorName,now);
     _product[traceNumber].traceNumber=traceNumber;
     _product[traceNumber].product=product;
     _product[traceNumber].valid=true;
     emit newProduct(traceNumber,productName,productType,msg.sender);
    }
    
    /**中间商操作接口*/    
    function addTraceInfoByMiddleman(uint256 traceNumber,string operatorName,uint256 quality) onlyMiddleMan public{
        require(_product[traceNumber].valid,"This product is not exist");
        MiddlemanData memory middleman=MiddlemanData(operatorName,quality,now);
        _product[traceNumber].middleman=middleman;
        emit addTraceInfoByMiddleman_event(traceNumber,quality,operatorName);
    }
    /**中超市商操作接口*/   
    function addTraceInfoBySuperMarket(uint256 traceNumber,string operatorName,uint256 	quality) onlySuperMarket public{
        require(_product[traceNumber].valid,"This product is not exist");
        SuperMarketData memory superMarket =SuperMarketData(operatorName,quality,now);
        _product[traceNumber].superMarket=superMarket;
        addTraceInfoBySuperMarket_event(traceNumber,quality,operatorName);
    }
    /**根据溯源码查询溯源信息接口,返回溯源数据的结构体*/     
    function getTraceInfo(uint256 traceNumber)returns(ProductData){
        return _product[traceNumber];
    }


    
}

23年国赛真题

pragma solidity ^0.4.25;

import "./Roles.sol";

//中间商角色
contract Distributor {
    using Roles for Roles.Role;

    event DistributorAdded(address indexed account);
    event DistributorRemoved(address indexed account);

    Roles.Role private _distributors;

    constructor (address  distributor ) public {
        _addDistributor(distributor);
    }

    modifier onlyDistributor() {
        require(isDistributor(msg.sender), "DistributorRole: caller does not have the Distributor role");
        _;
    }

    function isDistributor(address account) public view returns (bool) {
        return _distributors.has(account);
    }

    function addDistributor(address account) public onlyDistributor {
        _addDistributor(account);
    }

    function renounceDistributor() public {
        _removeDistributor(msg.sender);
    }

    function _addDistributor(address account) internal {
        _distributors.add(account);
        emit DistributorAdded(account);
    }

    function _removeDistributor(address account) internal {
        _distributors.remove(account);
        emit DistributorRemoved(account);
    }
}
pragma solidity >=0.4.22 <0.5.0;
pragma experimental ABIEncoderV2;

//食品信息管理合约
// 1.	保存食品基本信息:时间戳(流转过程中),用户名(流转过程中),用户地址信息(流转过程中),食品质量(流转过程中),食物名称,当前用户名称,质量,状态.
// 2.	对食品基本信息进行初始化
// 3.	实现两个方法:中间商添加食品信息;超市添加食品信息
// 4.	实现显示食品信息的方法

contract FoodInfoItem{
    //①保存食品流转过程中各个阶段的时间戳
    uint[] public _timestamp;
    //②保存食品流转过程各个阶段的用户名
    string[] public _traceName;
    //③保存食品流转过程各个阶段的用户地址信息(和用户一一对应)
    address[] public _traceAddress;
    //④保存食品流转过程中各个阶段的质量
    uint8[] public _traceQuality;
    //⑤食品名称
    string public _name;
    //⑥当前用户名称
    string public _currentTraceName;
    //⑦质量(0=优质 1=合格 2=不合格)
    uint8 public _quality; 
    //⑧状态(0:生产 1:分销 2:出售)
    uint8 public _status;
    //⑨初始化owner
    address public _owner;

  constructor (string name, string traceName, uint8 quality, address producer) public {
        _timestamp.push(now);
        _traceName.push(traceName);
        _traceAddress.push(producer);
        _traceQuality.push(quality);
        _name = name;
        _currentTraceName = traceName;
        _quality = quality;
        _status = 0;
        _owner = msg.sender;
    }

    function addTraceInfoByDistributor(string traceName,address distributor, uint8 quality) public returns(bool) {
        require(_status == 0 , "status must be producing");
        //②
        require(msg.sender==_owner,"aaaa");
        _timestamp.push(now);
        _traceName.push(traceName);
        _currentTraceName = traceName;
        //③
        _traceAddress.push(distributor);
        //④
        _quality=quality;
        _traceQuality.push(_quality);
        _status = 1;
        return true;
    }

    function addTraceInfoByRetailer(string memory traceName,address retailer, uint8 quality) public returns(bool) {
        require(_status == 1 , "status must be distributing");
        //②
        require(msg.sender==_owner,"aaaa");
        _timestamp.push(now);
        _traceName.push(traceName);
        _currentTraceName = traceName;
        //③
         _traceAddress.push(retailer);
        //④
         _quality=quality;
        _traceQuality.push(_quality);
        _status = 2;
        return true;
    }
    function getTraceInfo() public constant returns(uint[], string[], address[], uint8[]) {
        return(_timestamp, _traceName, _traceAddress, _traceQuality);
    }

    function getFood() public constant returns(uint, string, string, string, address, uint8) {
        return(_timestamp[0], _traceName[0], _name, _currentTraceName, _traceAddress[0], _quality);
    }

}
pragma solidity ^0.4.25;

import "./Roles.sol";

//生产者角色
contract Producer {
    using Roles for Roles.Role;

    event ProducerAdded(address indexed account);
    event ProducerRemoved(address indexed account);

    Roles.Role private _producers;

    constructor (address producer) public {
        _addProducer(producer);
    }

    modifier onlyProducer() {
        require(isProducer(msg.sender), "ProducerRole: caller does not have the Producer role");
        _;
    }

    function isProducer(address account) public view returns (bool) {
        return _producers.has(account);
    }

    function addProducer(address account) public onlyProducer {
        _addProducer(account);
    }

    function renounceProducer() public {
        _removeProducer(msg.sender);
    }

    function _addProducer(address account) internal {
        _producers.add(account);
        emit ProducerAdded(account);
    }

    function _removeProducer(address account) internal {
        _producers.remove(account);
        emit ProducerRemoved(account);
    }
}
pragma solidity ^0.4.25;

import "./Roles.sol";

//零售商角色(超市)
contract Retailer {
    using Roles for Roles.Role;

    event RetailerAdded(address indexed account);
    event RetailerRemoved(address indexed account);

    Roles.Role private _retailers;

    constructor (address retailer) public {
        _addRetailer(retailer);
    }

    modifier onlyRetailer() {
        require(isRetailer(msg.sender), "RetailerRole: caller does not have the Retailer role");
        _;
    }

    function isRetailer(address account) public view returns (bool) {
        return _retailers.has(account);
    }

    function addRetailer(address account) public onlyRetailer {
        _addRetailer(account);
    }

    function renounceRetailer() public {
        _removeRetailer(msg.sender);
    }

    function _addRetailer(address account) internal {
        _retailers.add(account);
        emit RetailerAdded(account);
    }

    function _removeRetailer(address account) internal {
        _retailers.remove(account);
        emit RetailerRemoved(account);
    }
}
pragma solidity ^0.4.25;
//角色库(管理所有角色地址)
// 1. 实现增加角色地址
// 2. 移除角色地址
// 3. 判断角色地址是否被授权
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }
    function add(Role storage role, address account) internal {
        require(!has(role,account), "Roles: account already has role");
        role.bearer[account] = true;
    }
    function remove(Role storage role, address account) internal {
        require(has(role,account), "Roles: account does not have role");
        role.bearer[account] = false;
    }
    function has(Role storage role, address account) internal view returns (bool) {
        require(account!=address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
    
}
pragma solidity >=0.4.22 <0.7.0;
pragma experimental ABIEncoderV2;
import "./FoodInfoItem.sol";
import "./Distributor.sol";
import "./Producer.sol";
import "./Retailer.sol";

//食品溯源合约(负责具体食品溯源信息的生成)
//  1.实现生产食品的方法(新建食品信息)
//  2.实现食品分销过程中增加溯源信息的接口
//  3.实现食品出售过程中增加溯源信息的接口
//  4.实现获取食品溯源信息接口

contract Trace is Producer, Distributor, Retailer{

        mapping (uint256 => address)  foods;//食品溯源id到具体食品溯源合约的映射表
        uint[]  foodList;

        //构造函数
        constructor(address producer, address distributor, address retailer)
	public Producer(producer)
	Distributor(distributor)
	Retailer(retailer){

        }
        //生成食品溯源信息接口
        //只有Producer能调用
        //name 食品名称
        //traceNumber 食品溯源id
        //traceName 当前用户名称
	    //quality 当前食品质量
        function newFood(string name,uint256 traceNumber, string traceName, uint8 quality)
	public onlyProducer returns(address)
        {
            //④
            require(foods[traceNumber]==address(0),"食物已存在");
            //⑤
            FoodInfoItem food=new FoodInfoItem(name,traceName,quality,msg.sender);
            //⑥
            foods[traceNumber]=food;
            //⑦
            foodList.push(traceNumber);
            //⑧
            return food;
        }

        //食品分销过程中增加溯源信息的接口
        //只有Distributor能调用
        //traceNumber 食品溯源id
        //traceName 当前用户名称
        //quality 当前食品质量
        function addTraceInfoByDistributor(uint256 traceNumber,string traceName, uint8 quality)
	public onlyDistributor returns(bool) {
            //③
            require(foods[traceNumber]!=address(0),"食品不存在");
            return FoodInfoItem(foods[traceNumber]).addTraceInfoByDistributor(traceName,msg.sender, quality);
        }

        //食品出售过程中增加溯源信息的接口
        //只有Retailer能调用
        //traceNumber 食品溯源id
        //traceName 当前用户名称
        //quality 当前食品质量
        function addTraceInfoByRetailer(uint256 traceNumber,string traceName, uint8 quality)
	public onlyRetailer returns(bool) {
            require(foods[traceNumber]!=address(0), "traceNumber does not exist");
            return FoodInfoItem(foods[traceNumber]).addTraceInfoByRetailer(traceName,msg.sender, quality);
        }

        //获取食品溯源信息接口
        //string[] 保存食品流转过程中各个阶段的相关信息
        //address[] 保存食品流转过程各个阶段的用户地址信息(和用户一一对应)
        //uint8[] 保存食品流转过程中各个阶段的状态变化
        function getTraceInfo(uint256 traceNumber) public constant returns(uint[], string[], address[], uint8[]) {
            require(foods[traceNumber] != address(0), "traceNumber does not exist");
            return FoodInfoItem(foods[traceNumber]).getTraceInfo();
        }

        function getFood(uint256 traceNumber) public constant returns(uint, string, string, string, address, uint8) {
            require(foods[traceNumber] != address(0), "traceNumber does not exist");
            return FoodInfoItem(foods[traceNumber]).getFood();
        }

        function getAllFood() public constant returns (uint[]) {
            return foodList;
        }
}

新能源合约(Table表操作)

/**
 * 电力能源详情存储器,记录电力能源详细信息
 */
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Table.sol";
import "./LibString.sol";
import "./Ownable.sol";


contract EnergyStorage is Ownable {

    using LibString for string;

    event Result(int count);

    TableFactory tf;
    string constant TABLE_NAME = "E_energy";
    string constant TABLE_NAME2 = "E_order";

    constructor() public {
        tf = TableFactory(0x1001);
        tf.createTable(TABLE_NAME, "num_id", "energy");

        tf.createTable(TABLE_NAME2, "id", "from,to,total,price");
    }


    /**
    * ""
    * 插入数据
    */
    function insert(string memory _numid) public returns(int) {
        int count = int(0);
        Table table = tf.openTable(TABLE_NAME);
        if(keccak256(_numid)!=keccak256("")){
            Entry entry = table.newEntry();
            entry.set("energy", int(0));
            count = table.insert(_numid,entry);
        }
        emit Result(count);
        return count;
    }
    
  
    function update(string memory _numid) public returns(int) {
        int count = int(0);
        int produce_random =rand();
        Table table = tf.openTable(TABLE_NAME);
        if(keccak256(_numid)!=keccak256("")){
            Entry entry = table.newEntry();
            entry.set("energy",_numid);
            count = table.insert(_numid,entry);
        }
        emit Result(count);
        return count;
    }
    
    /**
    * 通过key获取value,可以存在多个value
    */
    function select(string memory _numid) public view returns(int[] memory){
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        Entries entries = table.select(_numid, condition);
        
        int[] memory value_list = new int[](uint256(entries.size()));
        
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = entry.getInt("energy");
        }
        
        return value_list;

    }
    
    struct Total {
        uint Utotal;
        uint Usalltotal;
    }
    mapping(string => Total) totalmap;
    //能量总和
    function getEnergy(string memory _numid) public view returns(uint){
        // Total memory _total = totalmap(_numid);
        int[] memory value_list = select(_numid);
        uint total = 0;
        for (uint256 i = 0; i < value_list.length; i++) {
            // Arr[i] = uint(value_list[uint256(i)]);
            total += uint(value_list[uint256(i)]);
        }
        return total;

    }
    
    function update_sall(string memory _numid, uint sallE) public returns(bool){
        Total _total = totalmap[_numid];
        totalmap[_numid].Utotal = getEnergy(_numid);
        totalmap[_numid].Usalltotal = sallE;
        totalmap[_numid].Utotal -= sallE;
        return true;
    }       
    
    
    function remove(string memory _numid, string memory _energy) public returns(int) {
        int count = int(0);
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        condition.EQ("energy",_energy);
        count = table.remove(_numid,condition);  
        emit Result(count);
        return count;        
    }    

    //产生随机数
    function rand() private view returns(int) {
        int rand = int(keccak256(abi.encodePacked(block.difficulty, now))) % 100;
        if(rand < 70 && rand > 50){rand += 60;}
        if(rand < 50 && rand > 40){rand += 70;}
        if(rand < 40 && rand > 30){rand += 80;}
        if(rand < 30 && rand > 20){rand += 90;}
        if(rand < 20){rand += 100;}
        if(rand <= 0){rand += 110;}
        return rand;
    } 
    
    function uint2str(uint i) internal returns (string c) {
        if (i == 0) return "0";
        uint j = i;
        uint length;
        while (j != 0){
            length++;
            j /= 10;
        }
        bytes memory bstr = new bytes(length);
        uint k = length - 1;
        while (i != 0){
            bstr[k--] = byte(48 + i % 10);
            i /= 10;
        }
        c = string(bstr);
    }
    
    
    function getDate() public view returns(string) {
        uint time = uint(now);
        return uint2str(time);
    }
    //记录该地址的交易订单
    function insert2(string memory _id,  string memory _from, string memory _to, int _total, string memory _price) 
    public returns(int) 
    {
        int count = int(0);
        // int _data = getDate();
        Table table = tf.openTable(TABLE_NAME2);
        Entry entry = table.newEntry();
        // entry.set("time", _data);
        entry.set("from",_from);
        entry.set("to",_to);
        entry.set("total",int(_total));
        entry.set("price",_price);
        count = table.insert(_id, entry);
        emit Result(count);
        return count;
    }
    //查询地址的交易订单
    function getOrder(string memory _id) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME2);
        Condition condition = table.newCondition();
        Entries entries = table.select(_id, condition);
        
        string[] memory value_list = new string[](uint256(entries.size()));
        
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = _returnData(entry);
            
        }
        return value_list;
    }    
    

    // function convertGoods(string memory _str) private returns(Order){
    //     string[] memory ss = _str.split(",");
    //     return Order(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5]);
    // }

    // function convertEntry(Order memory _order, Entry entry) private {
    //     entry.set("id",_order._UAddress);
    //     entry.set("num",_order._id);
    //     entry.set("from",_order._from);
    //     entry.set("to",_order._to);
    //     entry.set("total",_order._total);
    //     entry.set("price",_order._price);
        
    // }   
    
    //拼接成json数据
    function _returnData(Entry _entry) internal view returns(string){

        string memory _json = "{";

        _json = _json.concat("'from':'");
        _json = _json.concat(_entry.getString("from"));
        _json = _json.concat("',");

        _json = _json.concat("'to':'");
        _json = _json.concat(_entry.getString("to"));
        _json = _json.concat("',");
        
        _json = _json.concat("'total':'");
        _json = _json.concat(_entry.getString("total"));
        _json = _json.concat("',");
        
        _json = _json.concat("'price':'");
        _json = _json.concat(_entry.getString("price"));
        _json = _json.concat("'");


        _json = _json.concat("}");

        return _json;
    }    
    
    // struct Order{
    //     string _UAddress;
    //     string _id;
    //     string _from;
    //     string _to;
    //     string _total;
    //     string _price;
    // }

    // struct Energy {
    //     string Ownership;
    //     string energy_loss; //能量损耗
    //     string energy_produce; //剩余能量
    //     string today_produce; //今日发电
    //     string tody_loss;//今日消耗
    //     string yesterday_produce;//昨日发电
    //     string yesterday_loss;//昨日消耗
    //     string week_produce;//本周发电
    //     string week_loss;//本周消耗
    //     string month_produce;//本月发电
    //     string month_loss;//本月消耗       

    // } 
    /**
    * 创建质押物品表
    * +---------------------------+----------------+-----------------------------------------+
    * | Field                     |     Type       |      Desc                               |
    * +---------------------------+----------------+-----------------------------------------+
    * | num_id                          string
    * | energy_loss;                    string          
      | energy_produce;                 string              
      | today_produce;                  string              
      | tody_loss;                      string
      | yesterday_produce;              string
      | yesterday_loss;                 string
      | week_produce;                   string
      | week_loss;                      string
      | month_produce;                  string
      | month_loss;                     string
    * +---------------------------+----------------+-----------------------------------------+
    */
}
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Ownable.sol";
import "./LibString.sol";
import "./Table.sol";

contract Interface is Ownable {

    using LibString for string;

    event PutResult(int count);

    TableFactory tf;
    string constant TABLE_NAME = "_interface";

    /**
    * map表
    * +----------------------+------------------------+-------------------------+
    * | Field                | Type                   | Desc                    |
    * +----------------------+------------------------+-------------------------+
    * | key                  | string                 | key                     |
    * | value                | string                 | value                   |
    * +----------------------+------------------------+-------------------------+
    */
    constructor() public {
        tf = TableFactory(0x1001);
        tf.createTable(TABLE_NAME, "Owner_ship", "num_id,sp_name,sp_actual_Power,sp_rated_Power,sp_input_Time,sp_position,sp_price");
    }

    /**
    * 插入数据,已有数据不添加
    */
    function put(string memory Owner_ship, string memory _value) public onlyOwner returns(int) {
        Assert memory _assert = convertAssert(_value);
        Table table = tf.openTable(TABLE_NAME);
        Entry entry = table.newEntry();
        convertEntry(_assert, entry);
        int count = table.insert(Owner_ship, entry);
        emit PutResult(count);
        return count;
    }
    
    /**
    * 通过key获取value,可以存在多个value
    */
    function get(string memory _key) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        Entries entries = table.select(_key, condition);
        string[] memory value_list = new string[](uint256(entries.size()));
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = _returnData(entry);
            
        }
        return value_list;
    }
    
    function convertAssert(string memory _str) private returns(Assert){
        string[] memory ss = _str.split(",");
        return Assert(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7]);
    }

    function convertEntry(Assert memory _assert, Entry entry) private {
        entry.set("num_id",_assert.numid);
        entry.set("sp_name",_assert.name);
        entry.set("sp_actual_Power",_assert.actual_Power);
        entry.set("sp_rated_Power",_assert.rated_Power);
        entry.set("sp_input_Time",_assert.input_Time);
        entry.set("sp_position",_assert.position);
        entry.set("sp_price",_assert.price);
        entry.set("Owner_ship",_assert.Ownership);

    }

    //拼接成json数据
    function _returnData(Entry _entry) internal view returns(string){

        string memory _json = "{";
        
        _json = _json.concat("'numid':'");
        _json = _json.concat(_entry.getString("num_id"));
        _json = _json.concat("',");

        _json = _json.concat("'name':'");
        _json = _json.concat(_entry.getString("sp_name"));
        _json = _json.concat("',");

        _json = _json.concat("'actual_Power':'");
        _json = _json.concat(_entry.getString("sp_actual_Power"));
        _json = _json.concat("',");

        _json = _json.concat("'rated_Power':'");
        _json = _json.concat(_entry.getString("sp_rated_Power"));
        _json = _json.concat("',");

        _json = _json.concat("'input_Time':'");
        _json = _json.concat(_entry.getString("sp_input_Time"));
        _json = _json.concat("',");

        _json = _json.concat("'position':'");
        _json = _json.concat(_entry.getString("sp_position"));
        _json = _json.concat("',");

        _json = _json.concat("'price':'");
        _json = _json.concat(_entry.getString("sp_price"));
        _json = _json.concat("',");
        
        _json = _json.concat("'Ownership':'");
        _json = _json.concat(_entry.getString("Owner_ship"));
        _json = _json.concat("'");

        _json = _json.concat("}");

        return _json;
    }
    
    struct Assert {
        string numid; //编号
        string name; //太阳能板名称
        string actual_Power; //实际功率(单位:W)
        string rated_Power; //额定功率(单位:W)
        string input_Time; //生效时间(单位:h)
        string position; //投放位置
        string price; //单价 (单位:元)
        string Ownership; //所属权(address)
    }

}
/*
 * Copyright 2014-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * */
 
pragma solidity ^0.4.25;

library LibString{
    

    function lenOfChars(string memory src) internal pure returns(uint){
        uint i=0;
        uint length = 0;
        bytes memory string_rep = bytes(src);
        //UTF-8 skip word
        while (i<string_rep.length)
        {
            i += utf8CharBytesLength(string_rep, i);
            length++;
        }
        return length;
    }

    function lenOfBytes(string memory src) internal pure returns(uint){
        bytes memory srcb = bytes(src);
        return srcb.length;
    }
    
    
    function startWith(string memory src, string memory prefix) internal pure returns(bool){
        bytes memory src_rep = bytes(src);
        bytes memory prefix_rep = bytes(prefix);
        
        if(src_rep.length < prefix_rep.length){
            return false;
        }
        
        uint needleLen = prefix_rep.length;
        for(uint i=0;i<needleLen;i++){
            if(src_rep[i] != prefix_rep[i]) return false;
        }
        
        return true;
    }
    
    function endWith(string memory src, string memory tail) internal pure returns(bool){
        bytes memory src_rep = bytes(src);
        bytes memory tail_rep = bytes(tail);
        
        if(src_rep.length < tail_rep.length){
            return false;
        }
        uint srcLen = src_rep.length;
        uint needleLen = tail_rep.length;
        for(uint i=0;i<needleLen;i++){
            if(src_rep[srcLen-needleLen+i] != tail_rep[i]) return false;
        }
        
        return true;    
    }
    

    function equal(string memory self, string memory other) internal pure returns(bool){
        bytes memory self_rep = bytes(self);
        bytes memory other_rep = bytes(other);
        
        if(self_rep.length != other_rep.length){
            return false;
        }
        uint selfLen = self_rep.length;
        for(uint i=0;i<selfLen;i++){
            if(self_rep[i] != other_rep[i]) return false;
        }
        return true;           
    }

    function equalNocase(string memory self, string memory other) internal pure returns(bool){
        return compareNocase(self, other) == 0;
    }
    
    function empty(string memory src) internal pure returns(bool){
        bytes memory src_rep = bytes(src);
        if(src_rep.length == 0) return true;

        for(uint i=0;i<src_rep.length;i++){
            byte b = src_rep[i];
            if(b != 0x20 && b != byte(0x09) && b!=byte(0x0A) && b!=byte(0x0D)) return false;
        }

        return true;
    }

    function concat(string memory self, string memory str) internal returns (string memory  _ret)  {
        _ret = new string(bytes(self).length + bytes(str).length);

        uint selfptr;
        uint strptr;
        uint retptr;
        assembly {
            selfptr := add(self, 0x20)
            strptr := add(str, 0x20)
            retptr := add(_ret, 0x20)
        }
        
        memcpy(retptr, selfptr, bytes(self).length);
        memcpy(retptr+bytes(self).length, strptr, bytes(str).length);
    }
    
    //start is char index, not byte index
    function substrByCharIndex(string memory self, uint start, uint len) internal returns (string memory) {
        if(len == 0) return "";
        //start - bytePos
        //len - byteLen
        uint bytePos = 0;
        uint byteLen = 0;
        uint i=0;
        uint chars=0;
        bytes memory self_rep = bytes(self);
        bool startMet = false;
        //UTF-8 skip word
        while (i<self_rep.length)
        {
            if(chars == start){
                bytePos = i;
                startMet = true;
            }
            if(chars == (start + len)){
                byteLen = i - bytePos;
            }
            i += utf8CharBytesLength(self_rep, i);
            chars++;
        }
        if(chars == (start + len)){
            byteLen = i - bytePos;
        }
        require(startMet, "start index out of range");
        require(byteLen != 0, "len out of range");
        
        string memory ret = new string(byteLen);

        uint selfptr;
        uint retptr;
        assembly {
            selfptr := add(self, 0x20)
            retptr := add(ret, 0x20)
        }
        
        memcpy(retptr, selfptr+bytePos, byteLen);
        return ret;
    }

    function compare(string memory self, string memory other) internal pure returns(int8){
        bytes memory selfb = bytes(self);
        bytes memory otherb = bytes(other);
        //byte by byte
        for(uint i=0;i<selfb.length && i<otherb.length;i++){
            byte b1 = selfb[i];
            byte b2 = otherb[i];
            if(b1 > b2) return 1;
            if(b1 < b2) return -1;
        }
        //and length
        if(selfb.length > otherb.length) return 1;
        if(selfb.length < otherb.length) return -1;
        return 0;
    }

    function compareNocase(string memory self, string memory other) internal pure returns(int8){
        bytes memory selfb = bytes(self);
        bytes memory otherb = bytes(other);
        for(uint i=0;i<selfb.length && i<otherb.length;i++){
            byte b1 = selfb[i];
            byte b2 = otherb[i];
            byte ch1 = b1 | 0x20;
            byte ch2 = b2 | 0x20;
            if(ch1 >= 'a' && ch1 <= 'z' && ch2 >= 'a' && ch2 <= 'z'){
                if(ch1 > ch2) return 1;
                if(ch1 < ch2) return -1;
            }
            else{
                if(b1 > b2) return 1;
                if(b1 < b2) return -1;
            }
        }

        if(selfb.length > otherb.length) return 1;
        if(selfb.length < otherb.length) return -1;
        return 0;
    }
    
    function toUppercase(string memory src) internal pure returns(string memory){
        bytes memory srcb = bytes(src);
        for(uint i=0;i<srcb.length;i++){
            byte b = srcb[i];
            if(b >= 'a' && b <= 'z'){
                b &= byte(0xDF);// -32
                srcb[i] = b ;
            }
        }
        return src;
    }
    
    function toLowercase(string memory src) internal pure returns(string memory){
        bytes memory srcb = bytes(src);
        for(uint i=0;i<srcb.length;i++){
            byte b = srcb[i];
            if(b >= 'A' && b <= 'Z'){
                b |= 0x20;
                srcb[i] = b;
            }
        }
        return src;
    }

    /**
     * Index Of
     *
     * Locates and returns the position of a character within a string
     * 
     * @param src When being used for a data type this is the extended object
     *              otherwise this is the string acting as the haystack to be
     *              searched
     * @param value The needle to search for, at present this is currently
     *               limited to one character
     * @return int The position of the needle starting from 0 and returning -1
     *             in the case of no matches found
     */
    function indexOf(string memory src, string memory value)
        internal
        pure
        returns (int) {
        return indexOf(src, value, 0);
    }

    /**
     * Index Of
     *
     * Locates and returns the position of a character within a string starting
     * from a defined offset
     * 
     * @param src When being used for a data type this is the extended object
     *              otherwise this is the string acting as the haystack to be
     *              searched
     * @param value The needle to search for, at present this is currently
     *               limited to one character
     * @param offset The starting point to start searching from which can start
     *                from 0, but must not exceed the length of the string
     * @return int The position of the needle starting from 0 and returning -1
     *             in the case of no matches found
     */
    function indexOf(string  memory src, string memory value, uint offset)
        internal
        pure
        returns (int) {
        bytes memory srcBytes = bytes(src);
        bytes memory valueBytes = bytes(value);

        assert(valueBytes.length == 1);

        for (uint i = offset; i < srcBytes.length; i++) {
            if (srcBytes[i] == valueBytes[0]) {
                return int(i);
            }
        }

        return -1;
    }

    function split(string memory src, string memory separator)
        internal
        pure
        returns (string[] memory splitArr) {
        bytes memory srcBytes = bytes(src);

        uint offset = 0;
        uint splitsCount = 1;
        int limit = -1;
        while (offset < srcBytes.length - 1) {
            limit = indexOf(src, separator, offset);
            if (limit == -1)
                break;
            else {
                splitsCount++;
                offset = uint(limit) + 1;
            }
        }

        splitArr = new string[](splitsCount);

        offset = 0;
        splitsCount = 0;
        while (offset < srcBytes.length - 1) {

            limit = indexOf(src, separator, offset);
            if (limit == - 1) {
                limit = int(srcBytes.length);
            }

            string memory tmp = new string(uint(limit) - offset);
            bytes memory tmpBytes = bytes(tmp);

            uint j = 0;
            for (uint i = offset; i < uint(limit); i++) {
                tmpBytes[j++] = srcBytes[i];
            }
            offset = uint(limit) + 1;
            splitArr[splitsCount++] = string(tmpBytes);
        }
        return splitArr;
    }

    //------------HELPER FUNCTIONS----------------
    
    function utf8CharBytesLength(bytes memory stringRep, uint ptr) internal pure returns(uint){
            
            if ((stringRep[ptr]>>7)==byte(0))
                return 1;
            if ((stringRep[ptr]>>5)==byte(0x06))
                return 2;
            if ((stringRep[ptr]>>4)==byte(0x0e))
                return 3;
            if ((stringRep[ptr]>>3)==byte(0x1e))
                return 4;
            return 1;
    }

    function memcpy(uint dest, uint src, uint len) private {
        // Copy word-length chunks while possible
        for(; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = 256 ** (32 - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }
    
}
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Ownable.sol";
import "./LibString.sol";
import "./Table.sol";

contract MapStorage is Ownable {

    using LibString for string;

    event PutResult(int count);

    TableFactory tf;
    string constant TABLE_NAME = "tx_map";

    /**
    * map表
    * +----------------------+------------------------+-------------------------+
    * | Field                | Type                   | Desc                    |
    * +----------------------+------------------------+-------------------------+
    * | key                  | string                 | key                     |
    * | value                | string                 | value                   |
    * +----------------------+------------------------+-------------------------+
    */
    constructor() public {
        tf = TableFactory(0x1001);
        tf.createTable(TABLE_NAME, "key", "value");
    }

    /**
    * 插入数据,已有数据不添加
    */
    function put(string memory _key, string memory _value) public onlyOwner returns(int) {
        int count = int(0);
        Table table = tf.openTable(TABLE_NAME);
        if(!_key.empty() && !_value.empty() && !_isExist(table, _key, _value)){
            Entry entry = table.newEntry();
            entry.set("value", _value);
            count = table.insert(_key, entry);
        }
        emit PutResult(count);
        return count;
    }

    /**
    * 通过key获取value,可以存在多个value
    */
    function get(string memory _key) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        Entries entries = table.select(_key, condition);
        string[] memory value_list = new string[](uint256(entries.size()));
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = entry.getString("value");
        }
        return value_list;

    }

    
    function remove(string memory _key, string memory _value) public returns(int) {
        int count = int(0);
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        condition.EQ("value",_value);
        count = table.remove(_key,condition);  
        emit PutResult(count);
        return count;        
    }

    function _isExist(Table _table, string memory _key, string memory _value) internal view returns(bool) {
        Condition condition = _table.newCondition();
        condition.EQ("value", _value);
        return _table.select(_key, condition).size() > int(0);
    }
}
/**
* 角色存储器/控制器  
*
*  主合约
*/
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./LibString.sol";
import "./Table.sol";
import "./MapStorage.sol";
import "./SolarPanelsStorage.sol";
import "./EnergyStorage.sol";
import "./Interface.sol";

contract NewEnergy {

    using LibString for string;
    MapStorage private mapStorage;
    SolarPanelsStorage private solarPanelsStorage;
    EnergyStorage private energyStorage;
    Interface private _interface;

    event AddRoleResult(int count);
    event RemoveRoleResult(int count);

    TableFactory tf;
    string constant TABLE_NAME = "tx_role";

    /**
    *  角色表
    * +----------------------+------------------------+-------------------------+
    * | Field                | Type                   | Desc                    |
    * +----------------------+------------------------+-------------------------+
    * | Uaddress             | string                 | 角色地址            
    * | role                 | string                 | 角色标识(用户或电力公司)
    * | password             | string                 | 用户密码                    
    * | Assert               | string[]
    * +----------------------+------------------------+-------------------------+
    */

    string constant private U_Role = "用户";	// 用户
    string constant private EC_Role = "电力公司";	// 电力公司

    constructor() public {
        tf = TableFactory(0x1001);
        tf.createTable(TABLE_NAME, "Uaddress", "role,password,Assert");
        // 资产:对应产生的能量
        mapStorage = new MapStorage();
        solarPanelsStorage = new SolarPanelsStorage();
        energyStorage = new EnergyStorage();
        _interface = new Interface();
    }
    

    /*
    描述 : 账户管理功能
    参数 :
            _Uaddress: 用户地址
            _role: 用户角色
            _password: 密码
    返回值 :
            return  > 0 注册成功
    功能   :
            account_register:注册账号
            account_removeRole:删除注销
            account_login:登录账号
    */
    /*
    **注册功能
    
    0x489e233ff7740af3eed0c542f3b007b38258cb1c

    0xb55d15fd16910c67e00b88cb38f0e24b8f3f5ce0
    */
    function account_register(string memory _Uaddress, string memory _role, string memory _password) public returns(int) {
        int count = int(0);
        Table table = tf.openTable(TABLE_NAME);
        if(!_Uaddress.empty() && !_password.empty() && !_isExist(table, _Uaddress, _password)){
            Entry entry = table.newEntry();
            entry.set("role", _role);
            entry.set("password", _password);
            count = table.insert(_Uaddress, entry);
        }
        emit AddRoleResult(count);
        return count;
    }

    /*
    **注销功能
    */
    function account_removeRole(string memory _Uaddress, string memory _role, string memory _password) public returns(int) {
        int count = int(0);
        Table table = tf.openTable(TABLE_NAME);
        if(!_Uaddress.empty() && !_password.empty() && !_isExist(table, _Uaddress, _password)){
            Condition condition = table.newCondition();
            condition.EQ("role", _role);
            condition.EQ("password", _password);
            count = table.remove(_Uaddress, condition);
        }
        emit RemoveRoleResult(count);
        return count;
    }

    
    function account_login(string memory _Uaddress, string memory _password) public view returns(bool){
        Table table = tf.openTable(TABLE_NAME);
        return _isExist(table, _Uaddress, _password);
    }

    function _isExist(Table _table, string memory _Uaddress, string memory _password) 
    internal view returns(bool) 
    {
        Condition condition = _table.newCondition();
        condition.EQ("password", _password);
        return _table.select(_Uaddress, condition).size() > int(0);
    }

    function onlyURole(string memory Uaddress) private view{
        Table table = tf.openTable(TABLE_NAME);
        require(only(table,Uaddress,U_Role), "not has u permission");
    }

    function onlyECRole(string memory Uaddress) private view{
        Table table = tf.openTable(TABLE_NAME);
        require(only(table, Uaddress, EC_Role), "not has ec permission");
    }  

    function only(Table _table, string memory _Uaddress, string memory _role) 
    internal view returns(bool) 
    {
        Condition condition = _table.newCondition();
        condition.EQ("role", _role);
        return _table.select(_Uaddress, condition).size() > int(0);
    }     
    //查询
    // function select(string memory _Uaddress) public view returns(string[] memory, string[] memory, string[] memory){
    //     Table table = tf.openTable(TABLE_NAME);
    //     Condition condition = table.newCondition();
    //     Entries entries = table.select(_Uaddress, condition);
        
    //     string[] memory value_list1 = new string[](uint256(entries.size()));

    //     for (int256 i = 0; i < entries.size(); ++i) {
    //         Entry entry = entries.get(i);

    //         value_list2[uint256(i)] = entry.getString("role");
    //         value_list3[uint256(i)] = entry.getString("password");
    //     }
    //     return (value_list1, value_list2, value_list3);        
        
    // }
    
    /*
    描述 : 资产管理
    参数 :
            _Uaddress: 用户地址
            _Assert: 太阳能板编号
    返回值 :
          true 成功
          false 失败
    功能 :
          Assert_put:添加资产
          Assert_get:获取资产列表
          Assert_remove:移除资产
    */    
    function Assert_put(string memory _Uaddress, string memory _Assert) public returns(int) {
        int count = mapStorage.put(_Uaddress, _Assert);
        return count;
    }
    
    function get_Address_Assert(string memory _Uaddress) public view returns(string[] memory){
        return mapStorage.get(_Uaddress);
    }
    
    function Assert_remove(string memory _Uaddress, string memory _Assert) public returns(int){
        int count = mapStorage.remove(_Uaddress, _Assert);
        return count;
    }

    /*
    描述 : 交易市场
    参数 :
            _goodsStr: 太阳能板详情信息
            _numid: 太阳能板编号
    返回值 :
          true 成功
          false 失败
    功能 :
          insert : 添加太阳能板
          transfer : 太阳能板转让
          saller : 出售太阳能板
          get_numid_Spu : 获取单个型号(numid)所有太阳能板信息
          get_Address_Spu: 获取账户(Uaddress)所有资产列表
          get_Spu_order: 获取购买订单记录
    */        
    /** 创建太阳能板
    *  Uaddress:  用户地址
    *  _goodsStr: 太阳能板信息
    *  _numid:   太阳能板编号
    */
    /*添加太阳能板(创建)
    GB/T 2296-2001
    * "GB/T 2296-2001,太阳能光伏板,150W/m^2,260W/m^2,20h,China,700RMB,0x489e233ff7740af3eed0c542f3b007b38258cb1c"
    * 插入数据
    用户1: 0xb55d15fd16910c67e00b88cb38f0e24b8f3f5ce0
    用户2: 0x6afa01e66ff8e8dad90836ede88188f90357d685
    */
    function SPU_insert(string _numid, string memory name,
    string memory actual_Power,string memory rated_Power,string memory input_Time,
    string memory position,string memory price,string Ownership) public returns(int256){
        onlyURole(Ownership);
        int256 count = solarPanelsStorage.insert(_numid,name,actual_Power,rated_Power,input_Time,position,price,Ownership);
        Assert_put(Ownership, _numid);
        energyStorage.insert(_numid);
        solarPanelsStorage.insert2(Ownership,_numid,name,actual_Power,rated_Power,input_Time,position,price);
        return count;
    }

    //更新太阳能板
    function SPU_update(string _numid, string _goodsStr, string Uaddress) public returns(int256){
        onlyURole(Uaddress);
        int256 count = solarPanelsStorage.update(_numid, _goodsStr);
        return count;
    }
    
    //太阳能板转让(购买)
    // Ownership: 所属权(用户地址)
    function SPU_transfer(string _numid, string Ownership, string Uaddress) public returns(int256){
        onlyURole(Uaddress);
        int256 count = solarPanelsStorage.transfer(_numid, Ownership);
        Assert_remove(Uaddress, _numid);
        Assert_put(Ownership, _numid);
        solarPanelsStorage.insertorder(Uaddress,Uaddress,Ownership,_numid);
        return count;
    }  

    /*
    ** 出售太阳能板
    ** Ownership: 所属权(用户地址)
    ** "GB/T 2296-2001, 600RMB , 0x489e233ff7740af3eed0c542f3b007b38258cb1c"
    */
    function SPU_saller(string _numid, string _price, string Uaddress) public returns(int256){
        onlyURole(Uaddress);
        int256 count = solarPanelsStorage.saller(_numid, _price);
        // solarPanelsStorage.saller2(Uaddress, _price);
        return count;
    }       

    //获取单个型号(numid)所有太阳能板信息
    function get_numid_Spu(string _numid) public view returns(string[] memory){
        return solarPanelsStorage.getDetail(_numid);
    }  
    
    //获取账户(Uaddress)所有资产列表
    function get_Address_Spu(string _Uaddress) public view returns(string[] memory){
        return solarPanelsStorage.select2(_Uaddress);
    }
    
    //获取购买订单记录
    function get_Spu_order(string _Uaddress) public view returns(string[] memory){
        return solarPanelsStorage.selectorder(_Uaddress);
    }
    
    /*
    描述 : 能源市场
    参数 :
            _goodsStr: 太阳能板详情信息
            _numid: 太阳能板编号
    返回值 :
          true 成功
          false 失败
    功能 :
          Energy_insert: 初始化
          Energy_update : 刷新
          get_numid_Energy: 查看能量列表(每日能量增长量)
          Energy_remove: 清除
          Energy_transfer: 出售能量
          get_Energy_Order: 获取订单列表
          get_Total_Energy: 获取总能量
    */   
    //
    function Energy_insert(string _numid) public returns(int){
        return energyStorage.insert(_numid);
    }
    
    function Energy_update(string _numid) public returns(int){
        return energyStorage.update(_numid);
    }

    function get_numid_Energy(string _numid) public view returns(int[] memory){
        return energyStorage.select(_numid);
    }

    function Energy_remove(string _numid, string _energy) public returns(int){
        return energyStorage.remove(_numid, _energy);
    }

    function Energy_transfer(string _from, string _to, uint _total, string _price) public returns(int) {
        // uint total = energyStorage.getEnergy(_from);
        energyStorage.update_sall(_from,_total);
        return energyStorage.insert2(_from,_from,_to,int(_total),_price);
    }

    function get_Energy_Order(string _numid) public view returns(string[] memory){
        return energyStorage.getOrder(_numid);
    }

    function get_Total_Energy(string _numid) public view returns(uint) {
        return energyStorage.getEnergy(_numid);
    }

}
pragma solidity ^0.4.25;

contract Ownable {
  address public owner;

  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

  function Ownable() public {
    owner = msg.sender;
  }

  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }
  
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}
// contract Ownable {
//     address private _owner;

//     event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

//     /**
//      *  The Ownable constructor sets the original `owner` of the contract to the sender
//      * account.
//      */
//     constructor () internal {
//         _owner = msg.sender;
//         emit OwnershipTransferred(address(0), _owner);
//     }

//     /**
//      *  the address of the owner.
//      */
//     function owner() public view returns (address) {
//         return _owner;
//     }

//     /**
//      *  Throws if called by any account other than the owner.
//      */
//     modifier onlyOwner() {
//         require(isOwner(), "Ownable: not authorized");
//         _;
//     }

//     /**
//      *  true if `msg.sender` is the owner of the contract.
//      */
//     function isOwner() public view returns (bool) {
//         return msg.sender == _owner;
//     }

//     /**
//      *  Allows the current owner to transfer control of the contract to a newOwner.
//      *  newOwner The address to transfer ownership to.
//      */
//     function transferOwnership(address newOwner) public onlyOwner {
//         _transferOwnership(newOwner);
//     }

//     /**
//      *  Transfers control of the contract to a newOwner.
//      *  newOwner The address to transfer ownership to.
//      */
//     function _transferOwnership(address newOwner) internal {
//         require(newOwner != address(0), "Ownable: newOwner not be zero");
//         emit OwnershipTransferred(_owner, newOwner);
//         _owner = newOwner;
//     }
// }
/**
 * 太阳能板详情存储器,记录太阳能板的详细信息
 */
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Table.sol";
import "./LibString.sol";
import "./Ownable.sol";
import "./MapStorage.sol";

contract SolarPanelsStorage is Ownable {

    using LibString for string;

    MapStorage private mapStorage;

    event InsertResult(int256);
    event UpdateResult(int256);

    TableFactory tf;
    string constant TABLE_NAME = "sp_goods";

    string constant TABLE_NAME2 = "_interface";
    
    string constant TABLE_NAME3 = "spu_order";

    /**
    * 创建太能能电池板实体
    * +---------------------------+----------------+-----------------------------------------+
    * | Field                     |     Type       |      Desc                               |
    * +---------------------------+----------------+-----------------------------------------+
    * | num_id                    | string                 | 编号
    * | sp_name                   | string                 | 太阳能板名称
    * | sp_actual_Power           | string                 | 实际功率(单位:W)
    * | sp_rated_Power            | string                 | 额定功率(单位:W)
    * | sp_input_Time             | string                 | 生效时间(单位:h)
    * | sp_position               | string                 | 投放位置
    * | sp_price                  | string                 | 单价 (单位:元)
    * | Owner_ship                | string                 | 所属权(address)
    * +---------------------------+----------------+-----------------------------------------+
    */
    constructor() public {
        tf = TableFactory(0x1001);
        tf.createTable(TABLE_NAME, "num_id", "sp_name,sp_actual_Power,sp_rated_Power,sp_input_Time,sp_position,sp_price,Owner_ship");
        tf.createTable(TABLE_NAME2, "Owner_ship", "num_id,sp_name,sp_actual_Power,sp_rated_Power,sp_input_Time,sp_position,sp_price");
        tf.createTable(TABLE_NAME3, "Owner_ship", "data,from,to,num_id");
        mapStorage = new MapStorage();
    }
//TABLE_NAME(表1)
    /**
    * "85414020.00,太阳能电池,150W,205W,20h,China,5000RMB,test"
    * 插入数据
    */
    function insert(string memory _numid, string memory name,
    string memory actual_Power,string memory rated_Power,string memory input_Time,
    string memory position,string memory price,string Ownership) public onlyOwner returns(int) {
        Table table = tf.openTable(TABLE_NAME);
        Entry entry = table.newEntry();
         //①将新增太阳能板数据存入指定表中
         entry.set("num_id",_numid);
         entry.set("sp_name",name);
         entry.set("sp_actual_Power",actual_Power);
         entry.set("sp_rated_Power",rated_Power);
         entry.set("sp_input_Time",input_Time);
         entry.set("sp_position",position);
         entry.set("sp_price",price);
         entry.set("Owner_ship",Ownership);
        int256 count = table.insert(Ownership,entry);
        emit InsertResult(count);
        return count;
    }

    /**
    *  "1,太阳能电池,150W,205W,20h,China,1000RMB,test"
    * 更新数据
    */
    function update(string memory _numid, string memory _goodsStr) public onlyOwner returns(int256) {
        Goods memory _goods = convertGoods(_goodsStr);
        Table table = tf.openTable(TABLE_NAME);
        require(_isnumidExist(table, _goods.numid),"太阳能电池不存在");
        Entry entry = table.newEntry();
        convertEntry( _goods , entry );
        Condition condition = table.newCondition();
        int256 count = table.update( _numid, entry , condition);
        emit UpdateResult(count);
        return count;
    }

    /**
    *  85414020.00
    *  test3
    *  更改所属权
    */
    function transfer(string memory _numid, string memory Ownership) public returns(int256) {
        
        Table table = tf.openTable(TABLE_NAME);
        // require(_isnumidExist(table, _numid), "update: current numid not exist");
        
        Entry entry = table.newEntry();
        entry.set("sp_price", "已出售");
        entry.set("Owner_ship", Ownership);
        
        Condition condition = table.newCondition();
        int256 count = table.update(_numid, entry, condition);
        emit UpdateResult(count);
        return count;
    }
    
    /**
    *  85414020.00
    *  test3
    *  更改单价
    */
    function saller(string memory _numid, string memory _price) public returns(int256) {
        int code = 0;
        
        Table table = tf.openTable(TABLE_NAME);
        require(_isnumidExist(table, _numid), "0");
        
        Entry entry = table.newEntry();
        entry.set("sp_price", _price);
        
        Condition condition = table.newCondition();
        int256 count = table.update(_numid, entry, condition);
        if(count != 1) {
            // 失败? 无权限或者其他错误?
            code = 0;
            return code;
        }
        emit UpdateResult(count);
        return count;
    }    
    
    /**
    * 通过numid查询数据
    */
    
    function getDetail(string memory _num_id) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        Entries entries = table.select(_num_id, condition);
        
        string[] memory value_list = new string[](uint256(entries.size()));
        
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = _returnData(entry);
            
        }
        return value_list;
    }

    
    function convertGoods(string memory _str) private returns(Goods){
        string[] memory ss = _str.split(",");
        return Goods(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7]);
    }

    function convertEntry(Goods memory _goods, Entry entry) private {
        entry.set("num_id",_goods.numid);
        entry.set("sp_name",_goods.name);
        entry.set("sp_actual_Power",_goods.actual_Power);
        entry.set("sp_rated_Power",_goods.rated_Power);
        entry.set("sp_input_Time",_goods.input_Time);
        entry.set("sp_position",_goods.position);
        entry.set("sp_price",_goods.price);
        entry.set("Owner_ship",_goods.Ownership);
        
    }

    function _isnumidExist(Table _table, string memory _id) internal view returns(bool) {
        Condition condition = _table.newCondition();
        return _table.select(_id, condition).size() != int(0);
    }

    //拼接成json数据
    function _returnData(Entry _entry) internal view returns(string){

        string memory _json = "{";

        _json = _json.concat("'numid':'");
        _json = _json.concat(_entry.getString("num_id"));
        _json = _json.concat("',");

        _json = _json.concat("'name':'");
        _json = _json.concat(_entry.getString("sp_name"));
        _json = _json.concat("',");

        _json = _json.concat("'actual_Power':'");
        _json = _json.concat(_entry.getString("sp_actual_Power"));
        _json = _json.concat("',");

        _json = _json.concat("'rated_Power':'");
        _json = _json.concat(_entry.getString("sp_rated_Power"));
        _json = _json.concat("',");

        _json = _json.concat("'input_Time':'");
        _json = _json.concat(_entry.getString("sp_input_Time"));
        _json = _json.concat("',");

        _json = _json.concat("'position':'");
        _json = _json.concat(_entry.getString("sp_position"));
        _json = _json.concat("',");

        _json = _json.concat("'price':'");
        _json = _json.concat(_entry.getString("sp_price"));
        _json = _json.concat("',");

        _json = _json.concat("'Ownership':'");
        _json = _json.concat(_entry.getString("Owner_ship"));
        _json = _json.concat("'");


        _json = _json.concat("}");

        return _json;
    }

    struct Goods {
        string numid; //编号
        string name; //太阳能板名称
        string actual_Power; //实际功率(单位:W)
        string rated_Power; //额定功率(单位:W)
        string input_Time; //生效时间(单位:h)
        string position; //投放位置
        string price; //单价 (单位:元)
        string Ownership; //所属权(address)
    }

    /**
    * 插入数据,已有数据不添加
    */
    function insert2(string memory Owner_ship, string memory numid, string memory name,
    string memory actual_Power,string memory rated_Power,string memory input_Time,
    string memory position,string memory price) public onlyOwner returns(int) {
        // Assert memory _assert = convertAssert2(_value);
        Table table = tf.openTable(TABLE_NAME2);
        Entry entry = table.newEntry();
        // convertEntry2(_assert, entry);
        entry.set("num_id",numid);
        entry.set("sp_name",name);
        entry.set("sp_actual_Power",actual_Power);
        entry.set("sp_rated_Power",rated_Power);
        entry.set("sp_input_Time",input_Time);
        entry.set("sp_position",position);
        entry.set("sp_price",price);
        entry.set("Owner_ship",Owner_ship);
        int count = table.insert(Owner_ship, entry);
        return count;
    }
    
    /**
    * 通过key获取value,可以存在多个value
    */
    function select2(string memory _key) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME2);
        Condition condition = table.newCondition();
        Entries entries = table.select(_key, condition);
        string[] memory value_list = new string[](uint256(entries.size()));
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = _returnData2(entry);
            
        }
        return value_list;
    }

    // function saller2(string memory Owner_ship, string memory _price) public returns(int256) {
    //     int code = 0;
    //     Table table = tf.openTable(TABLE_NAME2);
    //     Entry entry = table.newEntry();
    //     entry.set("sp_price", _price);
    //     Condition condition = table.newCondition();
    //     int256 count = table.update(Owner_ship, entry, condition);
    //     if(count != 1) {
    //         // 失败? 无权限或者其他错误?
    //         code = 0;
    //         return code;
    //     }
    //     emit UpdateResult(count);
    //     return count;
    // }  
    
    
    function convertAssert2(string memory _str) private returns(Assert){
        string[] memory ss = _str.split(",");
        return Assert(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7]);
    }

    function convertEntry2(Assert memory _assert, Entry entry) private {
        entry.set("num_id",_assert.numid);
        entry.set("sp_name",_assert.name);
        entry.set("sp_actual_Power",_assert.actual_Power);
        entry.set("sp_rated_Power",_assert.rated_Power);
        entry.set("sp_input_Time",_assert.input_Time);
        entry.set("sp_position",_assert.position);
        entry.set("sp_price",_assert.price);
        entry.set("Owner_ship",_assert.Ownership);

    }

    //拼接成json数据
    function _returnData2(Entry _entry) internal view returns(string){

        string memory _json = "{";
        
        _json = _json.concat("numid:'");
        _json = _json.concat(_entry.getString("num_id"));
        _json = _json.concat("',");

        _json = _json.concat("name:'");
        _json = _json.concat(_entry.getString("sp_name"));
        _json = _json.concat("',");

        _json = _json.concat("actual_Power:'");
        _json = _json.concat(_entry.getString("sp_actual_Power"));
        _json = _json.concat("',");

        _json = _json.concat("rated_Power:'");
        _json = _json.concat(_entry.getString("sp_rated_Power"));
        _json = _json.concat("',");

        _json = _json.concat("input_Time:'");
        _json = _json.concat(_entry.getString("sp_input_Time"));
        _json = _json.concat("',");

        _json = _json.concat("position:'");
        _json = _json.concat(_entry.getString("sp_position"));
        _json = _json.concat("',");

        _json = _json.concat("price:'");
        _json = _json.concat(_entry.getString("sp_price"));
        _json = _json.concat("',");
        
        _json = _json.concat("Ownership:'");
        _json = _json.concat(_entry.getString("Owner_ship"));
        _json = _json.concat("'");

        _json = _json.concat("}");

        return _json;
    }
    
    struct Assert {
        string numid; //编号
        string name; //太阳能板名称
        string actual_Power; //实际功率(单位:W)
        string rated_Power; //额定功率(单位:W)
        string input_Time; //生效时间(单位:h)
        string position; //投放位置
        string price; //单价 (单位:元)
        string Ownership; //所属权(address)
    }




    function insertorder(string memory Owner_ship,string memory _from,string memory _to,string memory _numid) 
    public returns(int) {
        Table table = tf.openTable(TABLE_NAME3);
        Entry entry = table.newEntry();
        entry.set("from", _from);
        entry.set("to",_to);
        entry.set("num_id",_numid);
        
        int count = table.insert(Owner_ship, entry);
        return count;
    }

    function selectorder(string memory Owner_ship) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME3);
        Condition condition = table.newCondition();
        Entries entries = table.select(Owner_ship, condition);
        string[] memory value_list = new string[](uint256(entries.size()));
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list[uint256(i)] = _returnData3(entry);
            
        }
        return value_list;
    }
    
    function uint2str(uint i) internal returns (string c) {
        if (i == 0) return "0";
        uint j = i;
        uint length;
        while (j != 0){
            length++;
            j /= 10;
        }
        bytes memory bstr = new bytes(length);
        uint k = length - 1;
        while (i != 0){
            bstr[k--] = byte(48 + i % 10);
            i /= 10;
        }
        c = string(bstr);
    }
    
    function getDate() public view returns(string) {
        uint time = uint(now);
        return uint2str(time);
    }
    
    function _returnData3(Entry _entry) internal view returns(string){
        
        string memory _json = "{";

        _json = _json.concat("data:'");
        _json = _json.concat(getDate());
        _json = _json.concat("',");

        _json = _json.concat("from:'");
        _json = _json.concat(_entry.getString("from"));
        _json = _json.concat("',");

        _json = _json.concat("to:'");
        _json = _json.concat(_entry.getString("to"));
        _json = _json.concat("',");
        
        _json = _json.concat("num_id:'");
        _json = _json.concat(_entry.getString("num_id"));
        _json = _json.concat("'");

        _json = _json.concat("}");

        return _json;
    }
    
    // function getDetail(string memory _num_id) public view returns(string memory _json){
    //     Entry entry = select(_num_id);
    //     _json = _returnData(entry);
    // }
    

    // /**
    // *  通过numid获取实体
    // */
    // function select(string memory _numid) private view returns(Entry _entry){
    //     Table table = tf.openTable(TABLE_NAME);
    //     require(_isnumidExist(table, _numid), "select: current numid not exist");

    //     Condition condition = table.newCondition();
    //     _entry = table.select(_numid, condition).get(int(0));
    // }
    
    // function select2( string memory id) public view returns(string[] memory){
    //     Table table =tf.openTable(TABLE_NAME);
    //     // require(_isnumidExist(table, _numid), "select: current numid not exist");
        
    //     Condition condition = table.newCondition();
    //     // condition.limit(2);
    //     // condition.EQ("Owner_ship", _Owner_ship);
        
    //     Entries entries = table.select(id, condition);
    //     string[] memory list = new string[](uint256(entries.size()));
        
    //     for(int i = 0; i < entries.size(); ++i){
    //       Entry entry = entries.get(i);
           
    //       list[uint256(i)] = entry.getString("Owner_ship");
    //     }        
    //     return list;
    //     // _entry = table.select(_numid, condition).get(int(7));
    // }
    
    // function SelectOwnership(string memory _Owner_ship) public view returns(string, string){
    //     Table table = tf.openTable(TABLE_NAME);
    //     Condition condition = table.newCondition();
    //     Entries entries = table.select(_Owner_ship, condition);
    //     for(int i = 0; i < entries.size(); ++i){
    //       return select2(i);
    //     }
        
    // }
    
    // function select3(string memory _numid) public view returns (string[] memory,string[] memory,string[] memory,
    // string[] memory,string[] memory,string[] memory,string[] memory,string[] memory)
    // {
    //     Table table = tf.openTable(TABLE_NAME);

    //     Condition condition = table.newCondition();

    //     Entries entries = table.select(_numid, condition);
    //     string[] memory a = new string[](uint256(entries.size()));
    //     string[] memory b = new string[](uint256(entries.size()));
    //     string[] memory c = new string[](uint256(entries.size()));
    //     string[] memory d = new string[](uint256(entries.size()));
    //     string[] memory e = new string[](uint256(entries.size()));
    //     string[] memory f = new string[](uint256(entries.size()));
    //     string[] memory g = new string[](uint256(entries.size()));
    //     string[] memory h = new string[](uint256(entries.size()));

    //     for (int256 i = 0; i < entries.size(); ++i) {
    //         Entry entry = entries.get(i);

    //         a[uint256(i)] = entry.getString("numid");
    //         b[uint256(i)] = entry.getString("name");
    //         c[uint256(i)] = entry.getString("actual_Power");
    //         d[uint256(i)] = entry.getString("rated_Power");
    //         e[uint256(i)] = entry.getString("input_Time");
    //         f[uint256(i)] = entry.getString("position");
    //         g[uint256(i)] = entry.getString("price");
    //         h[uint256(i)] = entry.getString("Ownership");
    //     }

    //     return (a, b, c, d, e, f, g, h);        
    // }
}
pragma solidity ^0.4.24;

contract TableFactory {
    function openTable(string) public constant returns (Table);  // 打开表
    function createTable(string,string,string) public returns(int);  // 创建表
}

// 查询条件
contract Condition {
    //等于
    function EQ(string, int) public;
    function EQ(string, string) public;

    //不等于
    function NE(string, int) public;
    function NE(string, string)  public;

    //大于
    function GT(string, int) public;
    //大于或等于
    function GE(string, int) public;

    //小于
    function LT(string, int) public;
    //小于或等于
    function LE(string, int) public;

    //限制返回记录条数
    function limit(int) public;
    function limit(int, int) public;
}

// 单条数据记录
contract Entry {
    function getInt(string) public constant returns(int);
    function getAddress(string) public constant returns(address);
    function getBytes64(string) public constant returns(byte[64]);
    function getBytes32(string) public constant returns(bytes32);
    function getString(string) public constant returns(string);

    function set(string, int) public;
    function set(string, string) public;
    function set(string, address) public;
}

// 数据记录集
contract Entries {
    function get(int) public constant returns(Entry);
    function size() public constant returns(int);
}

// Table主类
contract Table {
    // 查询接口
    function select(string, Condition) public constant returns(Entries);
    // 插入接口
    function insert(string, Entry) public returns(int);
    // 更新接口
    function update(string, Entry, Condition) public returns(int);
    // 删除接口
    function remove(string, Condition) public returns(int);

    function newEntry() public constant returns(Entry);
    function newCondition() public constant returns(Condition);
}

pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;

import "./Ownable.sol";
import "./LibString.sol";
import "./Table.sol";

contract test is Ownable {

    using LibString for string;

    event PutResult(int count);

    TableFactory tf;
    string constant TABLE_NAME = "tx_map2";

    /**
    * map表
    * +----------------------+------------------------+-------------------------+
    * | Field                | Type                   | Desc                    |
    * +----------------------+------------------------+-------------------------+
    * | key                  | string                 | key                     |
    * | value                | string                 | value                   |
    * +----------------------+------------------------+-------------------------+
    */
    constructor() public {
        tf = TableFactory(0x1001);
        tf.createTable(TABLE_NAME, "key", "value1, value2, value3");
    }

    /**
    * 插入数据,已有数据不添加
    */
    function put(string memory _key, string memory _value1, string memory _value2, string memory _value3) public onlyOwner returns(int) {
        int count = int(0);
        // Map memory map = convertPledgeGoods(_value);
        Table table = tf.openTable(TABLE_NAME);
        if(!_key.empty()){
            Entry entry = table.newEntry();
            entry.set("value1",_value1);
            entry.set("value2",_value2);
            entry.set("value3",_value3);
            // convertEntry(map, entry);
            count = table.insert(_key, entry);
        }
        emit PutResult(count);
        return count;
    }

    function update(string memory _key,string memory _key2) public onlyOwner returns(int) {
        // int count = int(0);
        // Map memory map = convertPledgeGoods(_value);
        Table table = tf.openTable(TABLE_NAME);
  
        Entry entry = table.newEntry();
        entry.set("key",_key2);
        Condition condition = table.newCondition();
        int count = table.update(_key, entry, condition);
        
        return count;
    }
    
    /**
    * 通过key获取value,可以存在多个value
    */
    function get(string memory _key) public view returns(string[] memory){
        Table table = tf.openTable(TABLE_NAME);
        Condition condition = table.newCondition();
        Entries entries = table.select(_key, condition);
        string[] memory value_list1 = new string[](uint256(entries.size()));
        // string[] memory value_list2 = new string[](uint256(entries.size()));
        // string[] memory value_list3 = new string[](uint256(entries.size()));
        for (int256 i = 0; i < entries.size(); ++i) {
            Entry entry = entries.get(i);
            value_list1[uint256(i)] = _returnData(entry);
            // value_list1[uint256(i)] = entry.getString("value1");
            // value_list2[uint256(i)] = entry.getString("value2");
            // value_list3[uint256(i)] = entry.getString("value3");
            
        }
        return value_list1;

    }

    function getDetail(string memory _key) public view returns(string memory _json){
        Entry entry = select(_key);
        _json = _returnData(entry);
    }
    
    function select(string memory _key) private view returns(Entry _entry){
        Table table = tf.openTable(TABLE_NAME);

        Condition condition = table.newCondition();
        
        Entries entries = table.select(_key, condition);
        for (int256 i = 0; i < entries.size(); ++i) {
            _entry = entries.get(i);
            
        }
    }

    // function _isProcessIdExist(Table _table, string memory _id) internal view returns(bool) {
    //     Condition condition = _table.newCondition();
    //     return _table.select(_id, condition).size() != int(0);
    // }
    
    // function convertPledgeGoods(string memory _str) private returns(Map){
    //     string[] memory ss = _str.split(",");
    //     return Map(ss[0],ss[1],ss[2],ss[3]);
    // }
    
    // function convertEntry(Map memory map, Entry entry) private {
    //     entry.set("value1",map.value1);
    //     entry.set("value2",map.value2);
    //     entry.set("value3",map.value3);
    // }
    
    //拼接成json数据
    function _returnData(Entry _entry) internal view returns(string){
        
        string memory _json = "{";
        
        _json = _json.concat("'key':'");
        _json = _json.concat(_entry.getString("key"));
        _json = _json.concat("',");
        
        _json = _json.concat("'value1':'");
        _json = _json.concat(_entry.getString("value1"));
        _json = _json.concat("',");

        _json = _json.concat("'value2':'");
        _json = _json.concat(_entry.getString("value2"));
        _json = _json.concat("',");

        _json = _json.concat("'value3':'");
        _json = _json.concat(_entry.getString("value3"));
        _json = _json.concat("'");

        _json = _json.concat("}");

        return _json;
    }
    
    struct Map {
        string[] key;
        string[] value1;
        string[] value2; 
        string[] value3;

    }

}

学生成绩表合约(Table表操作)

pragma solidity ^0.4.25;
import "./Table.sol";
 
contract StudentScoreByCRUD{
 
	address private _owner;
 
	modifier onlyOwner{
		require(_owner == msg.sender, "Auth: only owner is authorized");
		_;
	}
 
	constructor () public {
		_owner = msg.sender;
	}
 
 
 
	event createEvent(address owner, string tableName);
	event insertEvent(address studentId, string courseName, int score);
	event updateEvent(address studentId, string courseName, int score);
	event removeEvent(address studentId, string courseName);
 
 
 
 
	// 创建成绩表
	function create() public onlyOwner returns(int){
 
		TableFactory tf = TableFactory(0x1001);
		int count = tf.createTable("stu_score", "student_id", "course_name, score");
		emit createEvent(msg.sender, "stu_score");
		return count;
 
	}
 
 
	// 插入成绩操作
	function insert(address studentId, string courseName, int score) public onlyOwner returns(int){
 
 
		TableFactory tf = TableFactory(0x1001);
		Table table = tf.openTable("stu_score");
 
		string memory stuIdStr = addressToString(studentId);
		Entry entry = table.newEntry();
		entry.set("student_id", stuIdStr);
		entry.set("course_name", courseName);
		entry.set("score", score);
 
		int count = table.insert(stuIdStr, entry);
		emit insertEvent(studentId, courseName, score);
		return count;
 
	}
 
 
	function addressToString(address addr) private pure returns(string) {
		// Convert addr to bytes
		bytes20 value = bytes20(uint160(addr));
		bytes memory strBytes = new bytes(42);
		// Encode hex prefix
		strBytes[0] = '0';
		strBytes[1] = 'x';
 
		// Encode bytes usig hex encoding
		for(uint i = 0; i < 20; i++){
			uint8 byteValue = uint8(value[i]);
			strBytes[2 + (i<<1)] = encode(byteValue >> 4);
			strBytes[3 + (i<<1)] = encode(byteValue & 0x0f);
		}
 
		return string(strBytes);
 
 
 
	}
 
 
	function encode(uint8 num) private pure returns(byte){
		// 0-9 -> 0-9
		if(num >= 0 && num <= 9){
			return byte(num + 48);
		}
		// 10-15 -> a-f
		return byte(num + 87);
	}
 
 
	// 更新成绩操作
	function update(address studentId, string courseName, int newScore) public onlyOwner returns(int){
 
		TableFactory tf = TableFactory(0x1001);
		Table table = tf.openTable("stu_score");
 
		Entry entry = table.newEntry();
		entry.set("score", newScore);
 
		string memory stuIdStr = addressToString(studentId);
		Condition condition = table.newCondition();
		condition.EQ("student_id", stuIdStr);
		condition.EQ("course_name", courseName);
 
		int count = table.update(stuIdStr, entry, condition);
		emit updateEvent(studentId, courseName, newScore);
 
		return count;
 
	}
 
	// 删除成绩操作
	function remove(address studentId, string courseName) public onlyOwner returns(int){
 
		TableFactory tf = TableFactory(0x1001);
		Table table = tf.openTable("stu_score");
 
		string memory stuIdStr = addressToString(studentId);
		Condition condition = table.newCondition();
		condition.EQ("student_id", stuIdStr);
		condition.EQ("course_name", courseName);
 
		int count = table.remove(stuIdStr, condition);
		emit removeEvent(studentId, courseName);
 
		return count;
 
	}
 
	// 查询成绩操作
	function select(address studentId, string courseName) public view returns(int, string){
 
		TableFactory tf = TableFactory(0x1001);
		Table table = tf.openTable("stu_score");
 
		string memory stuIdStr = addressToString(studentId);
		Condition condition = table.newCondition();
		condition.EQ("student_id", stuIdStr);
		condition.EQ("course_name", courseName);
 
		Entries entries = table.select(stuIdStr, condition);
 
		if(entries.size() == 0){
		    return (0, stuIdStr);
		}
		else{
		    
		    return (entries.get(0).getInt("score"), stuIdStr);
		}
 
	}
 
 
 
}
pragma solidity ^0.4.24;

contract TableFactory {
    function openTable(string) public constant returns (Table);  // 打开表
    function createTable(string,string,string) public returns(int);  // 创建表
}

// 查询条件
contract Condition {
    //等于
    function EQ(string, int) public;
    function EQ(string, string) public;

    //不等于
    function NE(string, int) public;
    function NE(string, string)  public;

    //大于
    function GT(string, int) public;
    //大于或等于
    function GE(string, int) public;

    //小于
    function LT(string, int) public;
    //小于或等于
    function LE(string, int) public;

    //限制返回记录条数
    function limit(int) public;
    function limit(int, int) public;
}

// 单条数据记录
contract Entry {
    function getInt(string) public constant returns(int);
    function getAddress(string) public constant returns(address);
    function getBytes64(string) public constant returns(byte[64]);
    function getBytes32(string) public constant returns(bytes32);
    function getString(string) public constant returns(string);

    function set(string, int) public;
    function set(string, string) public;
    function set(string, address) public;
}

// 数据记录集
contract Entries {
    function get(int) public constant returns(Entry);
    function size() public constant returns(int);
}

// Table主类
contract Table {
    // 查询接口
    function select(string, Condition) public constant returns(Entries);
    // 插入接口
    function insert(string, Entry) public returns(int);
    // 更新接口
    function update(string, Entry, Condition) public returns(int);
    // 删除接口
    function remove(string, Condition) public returns(int);

    function newEntry() public constant returns(Entry);
    function newCondition() public constant returns(Condition);
}

学位签合约

学位签一

// SPDX-License-Identifier: MIT
pragma solidity 0.4.25;

contract DegreeManagement {
  enum Role {Education, School, Tutor}

  struct DegreeCertificate {
    uint256 certificateId; // 学位证书ID
    string studentName; // 学生姓名
    string degreeName; // 学位名称
    address tutor; // 导师签名者地址
    address school; //  学校签名者地址
    address education; // 教育部签名者地址
  }

  mapping(uint256 => DegreeCertificate) public certificates; // 存储学位证书的映射
  uint256 public certificateCount; // 学位证书数量
  mapping(address => Role) public roles; // 存储角色的映射
  address private owner; // 合约拥有者

  event NewCertificate(uint256 certificateId, string studentName, string degreeName, address tutor);
  event SignCertificateBySchool(uint256 certificateId,address school);
  event SignCertificateByEducation(uint256 certificateId,address education);
  event RoleAssigned(address indexed account, Role role);
  modifier onlyOwner() {
    require(msg.sender == owner, "Access denied");
    _;
  }

  modifier onlyRole(Role _role) {
    require(roles[msg.sender] == _role, "Access denied");
    _;
  }

  constructor() public {
    owner = msg.sender;
    assignRole(msg.sender, Role.Education); // 将部署合约的账户设为教育机构角色
  }

  //判断证书是否完成所有签名
  function isSignAll(uint256 _certificateId)internal view returns(bool){
      if(certificates[_certificateId].tutor!=address(0)||certificates[_certificateId].school!=address(0)||certificates[_certificateId].education!=address(0)){
          return true;
      }else {
          return false;
      }
  }

  // 导师创建学位证书并签名
  function createCertificate(string memory _studentName, string memory _degreeName) public onlyRole(Role.Tutor) returns (uint256) {
    certificateCount++;
    certificates[certificateCount] = DegreeCertificate(certificateCount, _studentName, _degreeName,msg.sender,address(0),address(0));
    emit NewCertificate(certificateCount, _studentName, _degreeName, msg.sender);
    return certificateCount;
  }

  // 学校签署学位证书
  function signCertificateBySchool(uint256 _certificateId) public onlyRole(Role.School) {
    require(certificates[_certificateId].certificateId != 0, "Certificate does not exist");
    require(certificates[_certificateId].school!=address(0), "Certificate already signed");
    certificates[_certificateId].school = msg.sender;
    SignCertificateBySchool(_certificateId,msg.sender);
  }
  
  // 教育部签署学位证书
  function signCertificateByEducation(uint256 _certificateId)public onlyRole(Role.Education) {
    require(certificates[_certificateId].certificateId != 0, "Certificate does not exist");
    require(certificates[_certificateId].education!=address(0), "Certificate already signed");
    certificates[_certificateId].school = msg.sender; 
    SignCertificateByEducation(_certificateId,msg.sender); 
  }

  // 分配角色
  function assignRole(address _account, Role _role) public onlyRole(Role.Education){
    roles[_account] = _role;
    emit RoleAssigned(_account, _role);
  }
  
  //通过学位证书ID查询证书信息
  function queryDegreeInfoById(uint256 _certificateId)public returns(uint256,string,string,address,address,address){
      require(isSignAll(_certificateId),"Degree do not have signed");
      return (certificates[_certificateId].certificateId,certificates[_certificateId].studentName,certificates[_certificateId].degreeName,certificates[_certificateId].tutor,certificates[_certificateId].school,certificates[_certificateId].education);
  }
}

学位签二

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

import "./Owneble.sol";

contract Character is Owneble {
    enum Role {Education, School, Tutor}

    mapping(address => Role) private roles;

    event RoleAdded(address indexed user, Role role);
    event RoleRemoved(address indexed user);

    modifier onlyRole(Role role) {
        require(roles[msg.sender] == role, "Only users with the specified role can call this function");
        _;
    }

    function addRole(address user, Role role) public onlyOwner {
        roles[user] = role;
        emit RoleAdded(user, role);
    }

    function removeRole(address user) public onlyOwner {
        delete roles[user];
        emit RoleRemoved(user);
    }

    function getRole(address user) public view returns (Role) {
        return roles[user];
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

import "./Evidence.sol";
import "./Signer.sol";

contract DegreeAwarding is Signer {
    Evidence private evidence;

    constructor(address evidenceAddress) public {
        evidence = Evidence(evidenceAddress);
    }

    function addRecord(string memory name, string memory studentId, string memory degreeType, uint256 score) public onlySigner {
        evidence.addRecord(name, studentId, degreeType, score);
    }

    function signRecord(bytes32 hash) public onlySigner {
        evidence.signRecord(hash);
    }

    function getRecord(bytes32 hash) public view returns (string memory, string memory, string memory, uint256, bool) {
        return evidence.getRecord(hash);
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

import "./Owneble.sol";

contract Evidence is Owneble {
    struct Record {
        string name;
        string studentId;
        string degreeType;
        uint256 score;
        bool signed;
    }

    mapping(bytes32 => Record) private records;

    event RecordAdded(bytes32 indexed hash);
    event RecordSigned(bytes32 indexed hash, address indexed signer);

    function addRecord(string memory name, string memory studentId, string memory degreeType, uint256 score) public onlyOwner {
        bytes32 hash = keccak256(abi.encodePacked(name, studentId, degreeType, score));
        require(records[hash].score == 0, "Record already exists");

        records[hash] = Record(name, studentId, degreeType, score, false);
        emit RecordAdded(hash);
    }

    function signRecord(bytes32 hash) public {
        require(records[hash].score != 0, "Record does not exist");
        require(!records[hash].signed, "Record already signed");

        records[hash].signed = true;
        emit RecordSigned(hash, msg.sender);
    }

    function getRecord(bytes32 hash) public view returns (string memory, string memory, string memory, uint256, bool) {
        Record memory record = records[hash];
        return (record.name, record.studentId, record.degreeType, record.score, record.signed);
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

contract Owneble {
    address public owner;

    constructor() public {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the contract owner can call this function");
        _;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        owner = newOwner;
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

import "./Owneble.sol";

contract Signer is Owneble {
    mapping(address => bool) private signers;

    event SignerAdded(address indexed signer);
    event SignerRemoved(address indexed signer);

    modifier onlySigner() {
        require(signers[msg.sender], "Only signers can call this function");
        _;
    }

    function addSigner(address signer) public onlyOwner {
        signers[signer] = true;
        emit SignerAdded(signer);
    }

    function removeSigner(address signer) public onlyOwner {
        signers[signer] = false;
        emit SignerRemoved(signer);
    }

    function isSigner(address signer) public view returns (bool) {
        return signers[signer];
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_74163644/article/details/139326796