solidity自定义合约,实现指定用户任务完成状态的存储和标记功能

需求为,使用solidity,实现自定义合约,功能类似Token的ERC20标准的合约,对于指定的用户,用bool进行标记,标记用户对应的任务是否已完成。

开发环境,vscode,hardhat

合约代码

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

contract TaskRepository {
    uint private total = 1;//记录任务完成标记次数,合约部署后初始化记录为1次
    address payable public owner;

    struct Ads {
        address account;//用户,此处为一个以太兼容的地址
        uint adId;//任务id
        bool complete;//任务是否完成标记
    }

    mapping(address =>  Ads[]) private  ads_complete_info;

    Ads[1] private  myStructs;//初始化用,默认合约创建者,标记为其任务101已完成

    event ReceiveTo(address caller, address receiver, uint adId, bool complete);

    constructor() {
        owner = payable(msg.sender);
        // 初始化结构体数组
        myStructs[0] = Ads(msg.sender, 101, true);
        ads_complete_info[msg.sender] = myStructs;
    }

    //修饰器所修饰的函数体会被插入到特殊符号_;的位置。
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    //由合约创建者调用,对指定用户,标记其任务为已完成状态
    //只能标记一次,不能重复标记,不能标记为 未完成 false
    function receiveTo(address account, uint adId, bool complete) external onlyOwner{
        //require(msg.sender == owner);
        Ads memory adComplete = Ads(account, adId, complete);
        bool foundFlag = false;
        Ads[] storage adCompleteBefore = ads_complete_info[account];
        for(uint i = 0; i < adCompleteBefore.length && adCompleteBefore.length>0;i++){
            if(adCompleteBefore[i].account == account && adCompleteBefore[i].adId == adId){
                require(adCompleteBefore[i].complete == false);
                adCompleteBefore[i].complete = complete;
                foundFlag = true;
            }
        }
        if(!foundFlag){
            adCompleteBefore.push(adComplete);
        }
        ads_complete_info[account] = adCompleteBefore;
        total += 1;
        emit ReceiveTo(msg.sender, account, adId, complete);
    }

    //查询任意一个用户,指定的任务adId,任务是否已完成
    function getAdIsComplete(address account, uint adId) external view returns (bool){
        if (ads_complete_info[account].length == 0) {
            return false;
        }
        
        Ads[] memory adCompleteBefore = ads_complete_info[account];
        for(uint i = 0; i < adCompleteBefore.length;i++){
            if(adCompleteBefore[i].account == account && adCompleteBefore[i].adId == adId){
                return adCompleteBefore[i].complete;
            }
        }
        return false;
    }

    //获取任务完成标记次数
    function totalCounts() external view returns (uint256) {
        return total;
    }
}

编译和部署的脚本如下

yarn hardhat clean
yarn hardhat compile
yarn hardhat run ./scripts/deployContract.js  --network sepolia

deployContract.js代码如下

async function main() {

    const [deployer] = await ethers.getSigners();
    console.log("Deploying contracts with the account:", deployer.address);
    //console.log("Account balance:", (await deployer.getBalance()).toString());
    const result = await ethers.getContractFactory("TaskRepository");
    console.log("deployed contract address:", result .address);
    
}
    
    main().then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });

项目的package.json文件如下

{
  "name": "solidity-demo1",
  "version": "1.0.0",
  "main": "index.js",
  "author": "liuyouzhang",
  "license": "MIT",
  "devDependencies": {
    "@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
    "@nomicfoundation/hardhat-ethers": "^3.0.0",
    "@nomicfoundation/hardhat-network-helpers": "^1.0.0",
    "@nomicfoundation/hardhat-toolbox": "^3.0.0",
    "@nomicfoundation/hardhat-verify": "^1.0.0",
    "@typechain/ethers-v6": "^0.4.0",
    "@typechain/hardhat": "^8.0.0",
    "chai": "^4.2.0",
    "ethers": "^6.4.0",
    "hardhat": "^2.19.0",
    "hardhat-gas-reporter": "^1.0.8",
    "solidity-coverage": "^0.8.0",
    "typechain": "^8.1.0"
  },
  "dependencies": {
    "@openzeppelin/contracts": "^4.9.0",
    "bignumber.js": "^9.1.2",
    "ethereumjs-tx": "^2.1.2",
    "express": "^4.18.2"
  }
}

调用代码如下./scripts/callTaskRepositoryContract.js

const ethers = require('ethers');
// const fs = require('fs');
// const Tx = require("ethereumjs-tx");// 这个版本一定要1.3.7
// const BigNumber = require("bignumber.js");
const abi = [
  {
   ......
  }
];
const provider = new ethers.getDefaultProvider('https://eth-sepolia.g.alchemy.com/v2/4s********************P');
const privateKey = "4fff6*************************************84".trim();
const wallet = new ethers.Wallet(privateKey, provider);
const ContractAddr ='0x5c11a7b3c871d04dac33ab8a2666d1a8fb089e66'
const contract = new ethers.Contract(ContractAddr, abi, provider);
const contractWithSigner = contract.connect(wallet);
module.exports = {
    // 标记任务完成
    receiveTo: async (req, res) => {
        const account = req.query.account;
        const adid = req.query.adid;
        let result = await contractWithSigner.receiveTo(account, adid, true);
        console.log("result:" + JSON.stringify(result) + "\n");
        //const bal = new BigNumber(result);
        // 发送响应数据
        res.json({
            "msg": "ok",
            "data": JSON.stringify(result),
        });
    },
    // 查询任务是否完成
    getAdIsComplete: async (req, res) => {
        const account = req.query.account;
        const adId = req.query.adid;
        console.log("request, account:" + account + ", adid: " + adId + "\n");
        let result = await contractWithSigner.getAdIsComplete(account, adId);
        console.log("get result success");
        console.log("result:" + JSON.stringify(result) + "\n");
        //const bal = new BigNumber(transaction.balanceOf());
        // 发送响应数据
        res.json({
            "msg": "ok",
            "result": JSON.stringify(result),
        });
    },
    // 查询total count
    totalCounts: async (req, res) => {
      let result = await contractWithSigner.totalCounts();
      console.log("result:" + JSON.stringify(result) + "\n");
      // 发送响应数据
      res.json({
          "msg": "ok",
          "result": JSON.stringify(result),
      });
  },
}

express服务启动代码./router/router.js

const express = require('express');
const app = new express();
const call = require('../scripts/callTaskRepositoryContract');
const router = express.Router();
const bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({extend: false}));
app.use(bodyParser.json());
app.use(router);

router.get('/api/finishTask', call.receiveTo);
router.get('/api/finishQuery', call.getAdIsComplete);

app.listen(5921, '0.0.0.0', () => console.log("正在监听端口"));

启动代码

node ./router/router.js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值